From be22b37ebe6b6808e8ad88f5bf955eb600082665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otakar=20Mare=C4=8Dek?= <otakarmare@outlook.com> Date: Fri, 7 Aug 2015 15:36:47 +0300 Subject: [PATCH 001/838] Add cache of configuration files list --- lib/internal/Magento/Framework/Module/Dir/Reader.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Module/Dir/Reader.php b/lib/internal/Magento/Framework/Module/Dir/Reader.php index 5f5167f88ef..36073670ca7 100644 --- a/lib/internal/Magento/Framework/Module/Dir/Reader.php +++ b/lib/internal/Magento/Framework/Module/Dir/Reader.php @@ -48,6 +48,13 @@ class Reader */ protected $fileIteratorFactory; + /** + * Cache storage + * + * @var array + */ + protected $cache = []; + /** * @param Dir $moduleDirs * @param ModuleListInterface $moduleList @@ -74,6 +81,9 @@ class Reader */ public function getConfigurationFiles($filename) { + if (isset($this->cache[$filename])) { + return $this->cache[$filename]; + } $result = []; foreach ($this->modulesList->getNames() as $moduleName) { $file = $this->getModuleDir('etc', $moduleName) . '/' . $filename; @@ -82,7 +92,7 @@ class Reader $result[] = $path; } } - return $this->fileIteratorFactory->create($this->modulesDirectory, $result); + return $this->cache[$filename] = $this->fileIteratorFactory->create($this->modulesDirectory, $result); } /** -- GitLab From 979d0419078f6df0f6ec264c4326935d554f55d1 Mon Sep 17 00:00:00 2001 From: Liam Wiltshire <liam@w.iltshi.re> Date: Tue, 22 Dec 2015 17:30:34 +0000 Subject: [PATCH 002/838] Update Template.php Updating the comment to reflect that in .phtml files $block is used rather than $this --- lib/internal/Magento/Framework/View/Element/Template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/Template.php b/lib/internal/Magento/Framework/View/Element/Template.php index 136ab328915..c0e4648398e 100644 --- a/lib/internal/Magento/Framework/View/Element/Template.php +++ b/lib/internal/Magento/Framework/View/Element/Template.php @@ -139,7 +139,7 @@ class Template extends AbstractBlock } /** - * Set template context. Sets the object that should represent $this in template + * Set template context. Sets the object that should represent $block in template * * @param \Magento\Framework\View\Element\BlockInterface $templateContext * @return void -- GitLab From dcbc801cbe8d46ef7a5ac785d66ad0a54f8773e1 Mon Sep 17 00:00:00 2001 From: Thai Phan <thai@outlook.com> Date: Tue, 26 Jan 2016 19:26:28 +1100 Subject: [PATCH 003/838] Update nginx.conf.sample I replaced the `?` characters with `$is_args`. `$is_args` returns `?` if a request line has arguments or an empty string if otherwise. --- nginx.conf.sample | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nginx.conf.sample b/nginx.conf.sample index 87b28aa9f69..1897d59bfae 100644 --- a/nginx.conf.sample +++ b/nginx.conf.sample @@ -65,7 +65,7 @@ location /update { } location / { - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } location /pub { @@ -105,7 +105,7 @@ location /static/ { } location /media/ { - try_files $uri $uri/ /get.php?$args; + try_files $uri $uri/ /get.php$is_args$args; location ~ ^/media/theme_customization/.*\.xml { deny all; @@ -115,13 +115,13 @@ location /media/ { add_header Cache-Control "public"; add_header X-Frame-Options "SAMEORIGIN"; expires +1y; - try_files $uri $uri/ /get.php?$args; + try_files $uri $uri/ /get.php$is_args$args; } location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { add_header Cache-Control "no-store"; add_header X-Frame-Options "SAMEORIGIN"; expires off; - try_files $uri $uri/ /get.php?$args; + try_files $uri $uri/ /get.php$is_args$args; } add_header X-Frame-Options "SAMEORIGIN"; } -- GitLab From fc46215f7a36eb8536016989c8a033d453b27ec1 Mon Sep 17 00:00:00 2001 From: Peter Halassek <peter.halassek@sitewards.com> Date: Tue, 8 Mar 2016 12:16:23 +0100 Subject: [PATCH 004/838] added partial fix for issue #2617. This way double opt in works and the id set before the confirmation mal is sent out. --- app/code/Magento/Newsletter/Model/Subscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 5ea6aefc0de..f9939fa6e0a 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -442,6 +442,7 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel $this->setStatusChanged(true); try { + $this->save(); if ($isConfirmNeed === true && $isOwnSubscribes === false ) { @@ -449,7 +450,6 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel } else { $this->sendConfirmationSuccessEmail(); } - $this->save(); return $this->getStatus(); } catch (\Exception $e) { throw new \Exception($e->getMessage()); -- GitLab From 81fafc014d72b812e2c505993ab43d7508027ff6 Mon Sep 17 00:00:00 2001 From: Vova Yatsyuk <vovayatsyuk@users.noreply.github.com> Date: Mon, 14 Mar 2016 18:38:07 +0200 Subject: [PATCH 005/838] Bugfix: Unable to activate search form on phone This commit fixes the bug, when user was not able to activate search form on mobile device after two sequential clicks on search icon (label). Bug description: 1. First click (Field should show up): `focus` event is triggered and form is shown. 2. Second click (Field should show off): `blur` and `focus` events are triggered 2.1. Blur event set the timeout to hide the field. 2.2. Focus event adds the `active` class to the field. 2.3. Timeout function is called and field becomes hidden. 2.4. Field is still has `focus` state, because user clicked on label again. 3. **Third click (Field should show up): `blur` and `focus` events are triggered again, and field will not show up.** Proposed patch adds additional logic into 2.1: **Blur event will set the timeout to hide the field if the field already has `active` class name** --- app/code/Magento/Search/view/frontend/web/form-mini.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Search/view/frontend/web/form-mini.js b/app/code/Magento/Search/view/frontend/web/form-mini.js index be0ae90a02a..77db9c5ce5b 100644 --- a/app/code/Magento/Search/view/frontend/web/form-mini.js +++ b/app/code/Magento/Search/view/frontend/web/form-mini.js @@ -58,6 +58,9 @@ define([ this.element.attr('autocomplete', this.options.autocomplete); this.element.on('blur', $.proxy(function () { + if (!this.searchLabel.hasClass('active')) { + return; + } setTimeout($.proxy(function () { if (this.autoComplete.is(':hidden')) { -- GitLab From b03bfd05cd683f779e60ad7472b354f7a17bc7cb Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@ebay.com> Date: Thu, 24 Mar 2016 11:00:55 +0200 Subject: [PATCH 006/838] MAGETWO-49763: JS validation is missed on required User-Agent fields on "Edit Design Configuration" Admin page --- .../view/adminhtml/ui_component/design_config_form.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Backend/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Backend/view/adminhtml/ui_component/design_config_form.xml index 6cbada2179f..2db844b952b 100644 --- a/app/code/Magento/Backend/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Backend/view/adminhtml/ui_component/design_config_form.xml @@ -69,6 +69,9 @@ <item name="fit" xsi:type="boolean">false</item> <item name="label" xsi:type="string">Search String</item> <item name="showFallbackReset" xsi:type="boolean">false</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> </item> </argument> </field> @@ -82,6 +85,9 @@ <item name="fit" xsi:type="boolean">false</item> <item name="label" xsi:type="string">Theme Name</item> <item name="showFallbackReset" xsi:type="boolean">false</item> + <item name="validation" xsi:type="array"> + <item name="required-entry" xsi:type="boolean">true</item> + </item> </item> </argument> </field> -- GitLab From 99ce20248230bfe69033f0cb1c7d79513bbfce29 Mon Sep 17 00:00:00 2001 From: Theis Corfixen <theiscorfixen@gmail.com> Date: Tue, 5 Apr 2016 13:17:05 +0200 Subject: [PATCH 007/838] Fixed post var name for update attributes Fixed request variable name for checking if attribute have been changed, so it matches template definition of this. Otherwise saving multiselect fields doesn't work when using update attributes from the dropdown in the default Product > Catalog Grid. --- .../Controller/Adminhtml/Product/Action/Attribute/Save.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php index abe72e14dd3..f878b89e14f 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php @@ -132,7 +132,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribut $attributesData[$attributeCode] = $value; } elseif ($attribute->getFrontendInput() == 'multiselect') { // Check if 'Change' checkbox has been checked by admin for this attribute - $isChanged = (bool)$this->getRequest()->getPost($attributeCode . '_checkbox'); + $isChanged = (bool)$this->getRequest()->getPost('toggle_' . $attributeCode); if (!$isChanged) { unset($attributesData[$attributeCode]); continue; -- GitLab From 1289010a6cb7638f0fb04034fedb0fe1c1886850 Mon Sep 17 00:00:00 2001 From: ikk0 <ikk0@users.noreply.github.com> Date: Tue, 3 May 2016 14:07:40 +0200 Subject: [PATCH 008/838] Fixed column description for "website_id" field in cataloginventory_stock_item Currently says "Is Divided into Multiple Boxes for Shipping". That's wrong. :-) Changed it to "Website ID". May need to be put into an upgrade schema instead. --- app/code/Magento/CatalogInventory/Setup/InstallSchema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php index 67a126f4a20..a19eb9d1cc5 100644 --- a/app/code/Magento/CatalogInventory/Setup/InstallSchema.php +++ b/app/code/Magento/CatalogInventory/Setup/InstallSchema.php @@ -249,7 +249,7 @@ class InstallSchema implements InstallSchemaInterface \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, 5, ['unsigned' => true, 'nullable' => false, 'default' => 0], - 'Is Divided into Multiple Boxes for Shipping' + 'Website ID' ) ->addIndex( $installer->getIdxName( -- GitLab From 66d19602e9627b2c446dd5445ff62bfbc2eea2b6 Mon Sep 17 00:00:00 2001 From: Aneurin Barker Snook <a@aneur.in> Date: Wed, 4 May 2016 10:12:21 +0100 Subject: [PATCH 009/838] don't hardcode the Magento_Backend::admin index --- .../Integration/Activate/Permissions/Tab/Webapi.php | 12 ++++++++++-- .../Block/Adminhtml/Integration/Edit/Tab/Webapi.php | 6 +++++- app/code/Magento/User/Block/Role/Tab/Edit.php | 10 +++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php b/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php index 81b558f3267..0c108b11a40 100644 --- a/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php +++ b/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php @@ -148,7 +148,11 @@ class Webapi extends \Magento\Backend\Block\Widget\Form\Generic implements public function getResourcesTreeJson() { $resources = $this->_resourceProvider->getAclResources(); - $aclResourcesTree = $this->_integrationData->mapResources($resources[1]['children']); + $configResource = array_filter($resources, function($node) { + return $node['id'] == 'Magento_Backend::admin'; + }); + $configResource = reset($configResource); + $aclResourcesTree = $this->_integrationData->mapResources($configResource['children']); return $this->encoder->encode($aclResourcesTree); } @@ -167,7 +171,11 @@ class Webapi extends \Magento\Backend\Block\Widget\Form\Generic implements $selectedResources = $this->_selectedResources; if ($this->isEverythingAllowed()) { $resources = $this->_resourceProvider->getAclResources(); - $selectedResources = $this->_getAllResourceIds($resources[1]['children']); + $configResource = array_filter($resources, function($node) { + return $node['id'] == 'Magento_Backend::admin'; + }); + $configResource = reset($configResource); + $selectedResources = $this->_getAllResourceIds($configResource['children']); } return $this->encoder->encode($selectedResources); } diff --git a/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php b/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php index ecd361aaadf..d6eb51cd279 100644 --- a/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php +++ b/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php @@ -176,8 +176,12 @@ class Webapi extends \Magento\Backend\Block\Widget\Form\Generic implements public function getTree() { $resources = $this->aclResourceProvider->getAclResources(); + $configResource = array_filter($resources, function($node) { + return $node['id'] == 'Magento_Backend::admin'; + }); + $configResource = reset($configResource); $rootArray = $this->integrationData->mapResources( - isset($resources[1]['children']) ? $resources[1]['children'] : [] + isset($configResource['children']) ? $configResource['children'] : [] ); return $rootArray; } diff --git a/app/code/Magento/User/Block/Role/Tab/Edit.php b/app/code/Magento/User/Block/Role/Tab/Edit.php index 81fe19eeff7..caf8a600076 100644 --- a/app/code/Magento/User/Block/Role/Tab/Edit.php +++ b/app/code/Magento/User/Block/Role/Tab/Edit.php @@ -198,9 +198,13 @@ class Edit extends \Magento\Backend\Block\Widget\Form implements \Magento\Backen */ public function getTree() { - $resources = $this->_aclResourceProvider->getAclResources(); - $rootArray = $this->_integrationData->mapResources( - isset($resources[1]['children']) ? $resources[1]['children'] : [] + $resources = $this->aclResourceProvider->getAclResources(); + $configResource = array_filter($resources, function($node) { + return $node['id'] == 'Magento_Backend::admin'; + }); + $configResource = reset($configResource); + $rootArray = $this->integrationData->mapResources( + isset($configResource['children']) ? $configResource['children'] : [] ); return $rootArray; } -- GitLab From e84b5a5c176ccbda91e0aa60fd18f0a11a943714 Mon Sep 17 00:00:00 2001 From: Raj KB <magepsycho@gmail.com> Date: Fri, 13 May 2016 17:22:32 +0400 Subject: [PATCH 010/838] Correction: variable naming for user roles & role id --- app/code/Magento/User/Block/User/Edit/Tab/Roles.php | 10 +++++----- .../Magento/User/Controller/Adminhtml/User/Save.php | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/User/Block/User/Edit/Tab/Roles.php b/app/code/Magento/User/Block/User/Edit/Tab/Roles.php index 8d835267fca..c3b2a5f7050 100644 --- a/app/code/Magento/User/Block/User/Edit/Tab/Roles.php +++ b/app/code/Magento/User/Block/User/Edit/Tab/Roles.php @@ -143,19 +143,19 @@ class Roles extends \Magento\Backend\Block\Widget\Grid\Extended //checking if we have this data and we //don't need load it through resource model if ($user->hasData('roles')) { - $uRoles = $user->getData('roles'); + $userRoles = $user->getData('roles'); } else { - $uRoles = $user->getRoles(); + $userRoles = $user->getRoles(); } if ($json) { $jsonRoles = []; - foreach ($uRoles as $urid) { - $jsonRoles[$urid] = 0; + foreach ($userRoles as $roleId) { + $jsonRoles[$roleId] = 0; } return $this->_jsonEncoder->encode((object)$jsonRoles); } else { - return $uRoles; + return $userRoles; } } } diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php index 048bf50ddba..f64f480d0bb 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Save.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php @@ -26,9 +26,9 @@ class Save extends \Magento\User\Controller\Adminhtml\User return; } $model->setData($this->_getAdminUserData($data)); - $uRoles = $this->getRequest()->getParam('roles', []); - if (count($uRoles)) { - $model->setRoleId($uRoles[0]); + $userRoles = $this->getRequest()->getParam('roles', []); + if (count($userRoles)) { + $model->setRoleId($userRoles[0]); } /** @var $currentUser \Magento\User\Model\User */ -- GitLab From 5cc1875be0a6c1fcb660040986a92a972931de5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Corr=C3=AAa=20Gomes?= <rafaelcg_stz@hotmail.com> Date: Sun, 15 May 2016 21:54:01 -0300 Subject: [PATCH 011/838] Create auth.json.sample Sample auth file like repository Magento Enterprise Cloud Edition --- auth.json.sample | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 auth.json.sample diff --git a/auth.json.sample b/auth.json.sample new file mode 100644 index 00000000000..81c8fd220ea --- /dev/null +++ b/auth.json.sample @@ -0,0 +1,8 @@ +{ + "http-basic": { + "repo.magento.com": { + "username": "<public-key>", + "password": "<private-key>" + } + } +} -- GitLab From d2d1d193204fcd3ca2d50b3a989157a88a03a513 Mon Sep 17 00:00:00 2001 From: Kristof Ringleff <kristof@fooman.co.nz> Date: Fri, 29 Apr 2016 20:51:11 +0200 Subject: [PATCH 012/838] Adds test for getDataUsingMethod using digits --- .../Magento/Framework/Test/Unit/ObjectTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/internal/Magento/Framework/Test/Unit/ObjectTest.php b/lib/internal/Magento/Framework/Test/Unit/ObjectTest.php index 96ecb2d8d27..11a9b697c44 100644 --- a/lib/internal/Magento/Framework/Test/Unit/ObjectTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/ObjectTest.php @@ -170,6 +170,22 @@ string', $mock->getDataUsingMethod('test_data'); } + /** + * Test documenting current behaviour of getDataUsingMethod + * _underscore assumes an underscore before any digit + */ + public function testGetDataUsingMethodWithoutUnderscore() + { + $this->_object->setData('key_1', 'value1'); + $this->assertTrue($this->_object->hasData('key_1')); + $this->assertEquals('value1', $this->_object->getDataUsingMethod('key_1')); + + $this->_object->setData('key2', 'value2'); + $this->assertEquals('value2', $this->_object->getData('key2')); + $this->assertEquals(null, $this->_object->getKey2()); + $this->assertEquals(null, $this->_object->getDataUsingMethod('key2')); + } + /** * Tests \Magento\Framework\DataObject->hasData() */ -- GitLab From c34bd624a7b742a19bc277cf4d8dac85c76edb40 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 17 May 2016 13:39:07 +0300 Subject: [PATCH 013/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed - and fix dnd --- .../Ui/view/base/web/js/dynamic-rows/dnd.js | 5 +- .../web/js/dynamic-rows/dynamic-rows-grid.js | 2 +- .../base/web/js/dynamic-rows/dynamic-rows.js | 111 +++++++++++++++++- 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js index e52177f74e4..594e300145b 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js @@ -131,7 +131,8 @@ define([ drEl.instance = recordNode = this.processingStyles(recordNode, elem); drEl.instanceCtx = this.getRecord(originRecord[0]); drEl.eventMousedownY = isTouchDevice ? event.originalEvent.touches[0].pageY : event.pageY; - drEl.minYpos = $table.offset().top - originRecord.offset().top + $table.find('thead').outerHeight(); + drEl.minYpos = + $table.offset().top - originRecord.offset().top + $table.find('thead').outerHeight(); drEl.maxYpos = drEl.minYpos + $table.find('tbody').outerHeight() - originRecord.outerHeight(); $tableWrapper.append(recordNode); @@ -189,7 +190,7 @@ define([ pageY = isTouchDevice ? event.originalEvent.touches[0].pageY : event.pageY, positionY = pageY - drEl.eventMousedownY; - drEl.depElement = this.getDepElement(drEl.instance, positionY); + drEl.depElement = this.getDepElement(drEl.instance, positionY, this.draggableElement.originRow); if (drEl.depElement) { depElementCtx = this.getRecord(drEl.depElement.elem[0]); diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index bbc6033df00..90e12a2bce3 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -22,7 +22,7 @@ define([ identificationDRProperty: 'id', listens: { 'insertData': 'processingInsertData', - 'recordData': 'initElements setToInsertData' + 'recordData': 'initElements setToInsertData, checkDefaultState' } }, diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 37df101b208..7c7b57b48df 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -36,6 +36,8 @@ define([ deleteValue: true, showSpinner: true, isDifferedFromDefault: false, + defaultState: [], + isDefaultState: true, fallbackResetTpl: 'ui/form/element/helper/fallback-reset-link', dndConfig: { name: '${ $.name }_dnd', @@ -60,9 +62,10 @@ define([ disabled: 'setDisabled', childTemplate: 'initHeader', recordTemplate: 'onUpdateRecordTemplate', - recordData: 'setDifferedFromDefault parsePagesData', + recordData: 'setDifferedFromDefault parsePagesData checkDefaultState', currentPage: 'changePage', - elems: 'checkSpinner' + elems: 'checkSpinner', + isDefaultState: 'updateTrigger' }, modules: { dnd: '${ $.dndConfig.name }' @@ -83,6 +86,7 @@ define([ */ initialize: function () { this._super() + .initDefaultState() .initChildren() .initDnd() .setColumnsHeaderListener() @@ -109,7 +113,8 @@ define([ 'disabled', 'labels', 'showSpinner', - 'isDifferedFromDefault' + 'isDifferedFromDefault', + 'isDefaultState' ]); return this; @@ -142,6 +147,106 @@ define([ return this; }, + /** + * Check default component state or not + * + * @param {Array} data - records data + */ + checkDefaultState: function (data) { + var result = true, + recordsData = utils.copy(this.recordData()) || data, + i = 0, + length = this.defaultState.length, + currentData = this.deleteProperty ? + _.filter(recordsData, function (elem) { + return elem[this.deleteProperty] !== this.deleteValue; + }, this) : recordsData; + + if (length !== currentData.length) { + this.isDefaultState(false); + + return; + } + + for (i; i < length; i++) { + if (!this._compareObject(this.defaultState[i], currentData[i])) { + result = false; + break; + } + } + + this.isDefaultState(result); + }, + + /** + * Compare objects. Compared only properties from origin object, + * if current object has more properties - they are not considered + * + * @param {Object} origin - first object + * @param {Object} current - second object + * + * @returns {Boolean} result - is equal this objects or not + */ + _compareObject: function (origin, current) { + var prop, + result = true; + + for (prop in origin) { + if (this._castValue(origin[prop]) != this._castValue(current[prop])) { + result = false; + break; + } + } + + return result; + }, + + /** + * Check value type and cast to boolean if needed + * + * @param {*} value + * + * @returns {Boolean|*} casted or origin value + */ + _castValue: function (value) { + if (_.isUndefined(value) || value === '' || _.isNull(value)) { + return false; + } else { + return value; + } + }, + + /** + * Init default component state + * + * @param {Array} data + * + * @returns Chainable. + */ + initDefaultState: function (data) { + var defaultState = data || utils.copy(this.recordData()); + + this.defaultState = defaultState; + + return this; + }, + + /** + * Triggered update event + * + * @param {Boolean} val + */ + updateTrigger: function (val) { + this.trigger('update', !val); + }, + + /** + * Was changes or not + */ + hasChanged: function () { + return !this.isDefaultState(); + }, + /** * Render column header */ -- GitLab From 2490db2e3c5315dbdd97b41a55cb553fc721ffef Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 17 May 2016 14:29:04 +0300 Subject: [PATCH 014/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 7c7b57b48df..d3c468895e8 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -148,7 +148,7 @@ define([ }, /** - * Check default component state or not + * Checks whether component's state is default or not * * @param {Array} data - records data */ @@ -192,7 +192,11 @@ define([ result = true; for (prop in origin) { - if (this._castValue(origin[prop]) != this._castValue(current[prop])) { + if (_.isObject(origin[prop]) && _.isObject(current[prop])) { + if (!this._compareObject(origin[prop], current[prop])) { + return false; + } + } else if (this._castValue(origin[prop]) != this._castValue(current[prop])) { result = false; break; } -- GitLab From 04364c7ad8913a129e21595c18cea84f2a43a752 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 17 May 2016 14:33:28 +0300 Subject: [PATCH 015/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index d3c468895e8..0e9d3541091 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -188,8 +188,7 @@ define([ * @returns {Boolean} result - is equal this objects or not */ _compareObject: function (origin, current) { - var prop, - result = true; + var prop; for (prop in origin) { if (_.isObject(origin[prop]) && _.isObject(current[prop])) { @@ -197,12 +196,11 @@ define([ return false; } } else if (this._castValue(origin[prop]) != this._castValue(current[prop])) { - result = false; - break; + return false; } } - return result; + return true; }, /** -- GitLab From 3a53abee9d82990757bc3881d56ee6365c958405 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 17 May 2016 16:30:36 +0300 Subject: [PATCH 016/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../base/web/js/dynamic-rows/dynamic-rows.js | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 0e9d3541091..dc8dd0ee42f 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -121,7 +121,7 @@ define([ }, /** - * Init DND module + * Inits DND module * * @returns {Object} Chainable. */ @@ -134,7 +134,7 @@ define([ }, /** - * Check columnsHeaderAfterRender property, + * Checks columnsHeaderAfterRender property, * and set listener on elems if needed * * @returns {Object} Chainable. @@ -149,12 +149,10 @@ define([ /** * Checks whether component's state is default or not - * - * @param {Array} data - records data */ - checkDefaultState: function (data) { + checkDefaultState: function () { var result = true, - recordsData = utils.copy(this.recordData()) || data, + recordsData = utils.copy(this.recordData()), i = 0, length = this.defaultState.length, currentData = this.deleteProperty ? @@ -179,7 +177,7 @@ define([ }, /** - * Compare objects. Compared only properties from origin object, + * Compares objects. Compares only properties from origin object, * if current object has more properties - they are not considered * * @param {Object} origin - first object @@ -204,7 +202,7 @@ define([ }, /** - * Check value type and cast to boolean if needed + * Checks value type and cast to boolean if needed * * @param {*} value * @@ -219,7 +217,7 @@ define([ }, /** - * Init default component state + * Inits default component state * * @param {Array} data * @@ -234,7 +232,7 @@ define([ }, /** - * Triggered update event + * Triggers update event * * @param {Boolean} val */ @@ -243,7 +241,7 @@ define([ }, /** - * Was changes or not + * Returns component state */ hasChanged: function () { return !this.isDefaultState(); -- GitLab From 8b4500055c69c62b02a23be664b06174d34d0ba0 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Mon, 23 May 2016 10:36:07 +0300 Subject: [PATCH 017/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../base/web/js/dynamic-rows/dynamic-rows.js | 52 ++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index dc8dd0ee42f..2446b124ab2 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -153,27 +153,49 @@ define([ checkDefaultState: function () { var result = true, recordsData = utils.copy(this.recordData()), - i = 0, - length = this.defaultState.length, currentData = this.deleteProperty ? _.filter(recordsData, function (elem) { return elem[this.deleteProperty] !== this.deleteValue; }, this) : recordsData; - if (length !== currentData.length) { - this.isDefaultState(false); + if (_.isArray(this.defaultState)) { + result = this._compareArrays(this.defaultState, currentData); + } + + this.isDefaultState(result); + }, + + /** + * Compares arrays. + * + * @param {Object} origin - first array + * @param {Object} current - second array + * + * @returns {Boolean} result - is equal this arrays or not + */ + _compareArrays: function (origin, current) { + var index = 0, + length = origin.length; - return; + if (origin.length !== current.length) { + return false; } - for (i; i < length; i++) { - if (!this._compareObject(this.defaultState[i], currentData[i])) { - result = false; - break; + for (index; index < length; index++) { + if (_.isArray(origin[index]) && _.isArray(current[index])) { + if (!this._compareArrays(origin[index], current[index])) { + return false; + } + } else if (typeof origin[index] === 'object' && typeof current[index] === 'object') { + if (!this._compareObject(origin[index], current[index])) { + return false; + } + } else if (this._castValue(origin[index]) != this._castValue(current[index])){ + return false } } - this.isDefaultState(result); + return true; }, /** @@ -189,12 +211,16 @@ define([ var prop; for (prop in origin) { - if (_.isObject(origin[prop]) && _.isObject(current[prop])) { + if (_.isArray(origin[prop]) && _.isArray(current[prop])) { + if (!this._compareArrays(origin[prop], current[prop])) { + return false; + } + } else if (typeof origin[prop] === 'object' && typeof current[prop] === 'object') { if (!this._compareObject(origin[prop], current[prop])) { return false; } - } else if (this._castValue(origin[prop]) != this._castValue(current[prop])) { - return false; + } else if (this._castValue(origin[prop]) != this._castValue(current[prop])){ + return false } } -- GitLab From 65e7a6dd2b0eb2a598fb109b5d4fff89dbb1ea79 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Mon, 23 May 2016 11:37:13 +0300 Subject: [PATCH 018/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed - fix codestyle --- .../base/web/js/dynamic-rows/dynamic-rows.js | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 2446b124ab2..e7fbf182f08 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -181,6 +181,7 @@ define([ return false; } + /*eslint-disable max-depth, eqeqeq */ for (index; index < length; index++) { if (_.isArray(origin[index]) && _.isArray(current[index])) { if (!this._compareArrays(origin[index], current[index])) { @@ -190,10 +191,10 @@ define([ if (!this._compareObject(origin[index], current[index])) { return false; } - } else if (this._castValue(origin[index]) != this._castValue(current[index])){ - return false + } else if (this._castValue(origin[index]) != this._castValue(current[index])) { + return false; } - } + }/*eslint-enable max-depth, eqeqeq */ return true; }, @@ -210,6 +211,7 @@ define([ _compareObject: function (origin, current) { var prop; + /*eslint-disable max-depth, eqeqeq*/ for (prop in origin) { if (_.isArray(origin[prop]) && _.isArray(current[prop])) { if (!this._compareArrays(origin[prop], current[prop])) { @@ -219,10 +221,10 @@ define([ if (!this._compareObject(origin[prop], current[prop])) { return false; } - } else if (this._castValue(origin[prop]) != this._castValue(current[prop])){ - return false + } else if (this._castValue(origin[prop]) != this._castValue(current[prop])) { + return false; } - } + }/*eslint-enable max-depth, eqeqeq */ return true; }, @@ -237,9 +239,9 @@ define([ _castValue: function (value) { if (_.isUndefined(value) || value === '' || _.isNull(value)) { return false; - } else { - return value; } + + return value; }, /** @@ -251,7 +253,7 @@ define([ */ initDefaultState: function (data) { var defaultState = data || utils.copy(this.recordData()); - + this.defaultState = defaultState; return this; @@ -270,7 +272,7 @@ define([ * Returns component state */ hasChanged: function () { - return !this.isDefaultState(); + return !this.isDefaultState(); }, /** -- GitLab From 5e00e7695d3e27ad8dce3c65a68f01277df14399 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 24 May 2016 15:30:42 +0300 Subject: [PATCH 019/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../base/web/js/dynamic-rows/dynamic-rows.js | 157 +++++++++--------- 1 file changed, 78 insertions(+), 79 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index e7fbf182f08..324e429e67f 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -14,6 +14,83 @@ define([ ], function (ko, utils, _, layout, uiCollection, registry, $t) { 'use strict'; + /** + * Compares arrays. + * + * @param {Array} base - array as method bases its decision on first argument. + * @param {Array} current - second array + * + * @returns {Boolean} result - is current array equal to base array + */ + function compareArrays(base, current) { + var index = 0, + length = base.length; + + if (base.length !== current.length) { + return false; + } + + /*eslint-disable max-depth, eqeqeq */ + for (index; index < length; index++) { + if (_.isArray(base[index]) && _.isArray(current[index])) { + if (!compareArrays(base[index], current[index])) { + return false; + } + } else if (typeof base[index] === 'object' && typeof current[index] === 'object') { + if (!compareObjects(base[index], current[index])) { + return false; + } + } else if (castValue(base[index]) != castValue(current[index])) { + return false; + } + }/*eslint-enable max-depth, eqeqeq */ + + return true; + } + + /** + * Compares objects. Compares only properties from origin object, + * if current object has more properties - they are not considered + * + * @param {Object} base - first object + * @param {Object} current - second object + * + * @returns {Boolean} result - is current object equal to base object + */ + function compareObjects(base, current) { + var prop; + + /*eslint-disable max-depth, eqeqeq*/ + for (prop in base) { + if (_.isArray(base[prop]) && _.isArray(current[prop])) { + if (!compareArrays(base[prop], current[prop])) { + return false; + } + } else if (typeof base[prop] === 'object' && typeof current[prop] === 'object') { + if (!compareObjects(base[prop], current[prop])) { + return false; + } + } else if (castValue(base[prop]) != castValue(current[prop])) { + return false; + } + }/*eslint-enable max-depth, eqeqeq */ + } + + /** + * Checks value type and cast to boolean if needed + * + * @param {*} value + * + * @returns {Boolean|*} casted or origin value + */ + function castValue(value) { + if (_.isUndefined(value) || value === '' || _.isNull(value)) { + return false; + } + + return value; + } + return uiCollection.extend({ defaults: { defaultRecord: false, @@ -159,90 +236,12 @@ define([ }, this) : recordsData; if (_.isArray(this.defaultState)) { - result = this._compareArrays(this.defaultState, currentData); + result = compareArrays(this.defaultState, currentData); } this.isDefaultState(result); }, - /** - * Compares arrays. - * - * @param {Object} origin - first array - * @param {Object} current - second array - * - * @returns {Boolean} result - is equal this arrays or not - */ - _compareArrays: function (origin, current) { - var index = 0, - length = origin.length; - - if (origin.length !== current.length) { - return false; - } - - /*eslint-disable max-depth, eqeqeq */ - for (index; index < length; index++) { - if (_.isArray(origin[index]) && _.isArray(current[index])) { - if (!this._compareArrays(origin[index], current[index])) { - return false; - } - } else if (typeof origin[index] === 'object' && typeof current[index] === 'object') { - if (!this._compareObject(origin[index], current[index])) { - return false; - } - } else if (this._castValue(origin[index]) != this._castValue(current[index])) { - return false; - } - }/*eslint-enable max-depth, eqeqeq */ - - return true; - }, - - /** - * Compares objects. Compares only properties from origin object, - * if current object has more properties - they are not considered - * - * @param {Object} origin - first object - * @param {Object} current - second object - * - * @returns {Boolean} result - is equal this objects or not - */ - _compareObject: function (origin, current) { - var prop; - - /*eslint-disable max-depth, eqeqeq*/ - for (prop in origin) { - if (_.isArray(origin[prop]) && _.isArray(current[prop])) { - if (!this._compareArrays(origin[prop], current[prop])) { - return false; - } - } else if (typeof origin[prop] === 'object' && typeof current[prop] === 'object') { - if (!this._compareObject(origin[prop], current[prop])) { - return false; - } - } else if (this._castValue(origin[prop]) != this._castValue(current[prop])) { - return false; - } - }/*eslint-enable max-depth, eqeqeq */ - - return true; - }, - - /** - * Checks value type and cast to boolean if needed - * - * @param {*} value - * - * @returns {Boolean|*} casted or origin value - */ - _castValue: function (value) { - if (_.isUndefined(value) || value === '' || _.isNull(value)) { - return false; - } - - return value; - }, /** * Inits default component state -- GitLab From 0812f6f8f4f3af957168bc9f8ec527e4eb0ab529 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 24 May 2016 16:51:59 +0300 Subject: [PATCH 020/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js | 4 ++-- .../Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 6 ++++++ .../base/web/templates/dynamic-rows/templates/default.html | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index 90e12a2bce3..16ce4e1620f 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -22,7 +22,7 @@ define([ identificationDRProperty: 'id', listens: { 'insertData': 'processingInsertData', - 'recordData': 'initElements setToInsertData, checkDefaultState' + 'recordData': 'initElements setToInsertData checkDefaultState' } }, @@ -46,7 +46,7 @@ define([ setToInsertData: function () { var insertData = [], obj; - + if (this.recordData().length && !this.update) { this.recordData.each(function (recordData) { obj = {}; diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 324e429e67f..4412388596e 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -74,6 +74,8 @@ define([ return false; } }/*eslint-enable max-depth, eqeqeq */ + + return true; } /** @@ -210,6 +212,10 @@ define([ return this; }, + compareArrays: function (o, r) { + return compareArrays(o,r); + }, + /** * Checks columnsHeaderAfterRender property, * and set listener on elems if needed diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index b69c6b0de65..b5f4541b648 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -51,7 +51,8 @@ <tfoot> <tr> - <td attr="{'colspan': element.getColumnsCount()}"> + <td attr="{'colspan': element.getColumnsCount()}" + visible="element.addButton"> <button if="element.addButton" attr="{disabled: disabled, 'data-action': 'add_new_row'}" type="button" -- GitLab From 09a78b307eb9306324ebe4077ae276d9e773a118 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 24 May 2016 17:01:03 +0300 Subject: [PATCH 021/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed --- .../Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 4412388596e..1f174c7fd04 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -212,10 +212,6 @@ define([ return this; }, - compareArrays: function (o, r) { - return compareArrays(o,r); - }, - /** * Checks columnsHeaderAfterRender property, * and set listener on elems if needed -- GitLab From d6363a374794277ff6d6052fed7243ee3f7d270b Mon Sep 17 00:00:00 2001 From: imelnychenko <imelnychenko@magento.com> Date: Thu, 26 May 2016 13:27:21 +0300 Subject: [PATCH 022/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Bundle/view/adminhtml/web/js/components/bundle-option-qty.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index a52d4e8a468..9b2c509cde6 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -18,6 +18,7 @@ define([ * update event */ onUpdate: function () { + this._super(); this.validation['validate-number'] = true; this.validation['validate-digits'] = this.isInteger; this.validate(); -- GitLab From f2da179f2e03d7a226948f2e487f5204cb9ff8df Mon Sep 17 00:00:00 2001 From: imelnychenko <imelnychenko@magento.com> Date: Thu, 26 May 2016 13:47:44 +0300 Subject: [PATCH 023/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Bundle/view/adminhtml/web/js/components/bundle-option-qty.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index 9b2c509cde6..f7492c223de 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -21,7 +21,6 @@ define([ this._super(); this.validation['validate-number'] = true; this.validation['validate-digits'] = this.isInteger; - this.validate(); } }); }); -- GitLab From f127a6404a1ebfb1a6ec16c52d2303207359c0ac Mon Sep 17 00:00:00 2001 From: imelnychenko <imelnychenko@magento.com> Date: Thu, 26 May 2016 14:40:49 +0300 Subject: [PATCH 024/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../view/adminhtml/web/js/components/bundle-option-qty.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index f7492c223de..2ba8ddfc36c 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -18,9 +18,10 @@ define([ * update event */ onUpdate: function () { - this._super(); + this.bubble('update', this.hasChanged()); this.validation['validate-number'] = true; this.validation['validate-digits'] = this.isInteger; + this.validate(); } }); }); -- GitLab From ff460388ade345eb1066276ca5571b78ed1c38ee Mon Sep 17 00:00:00 2001 From: imelnychenko <imelnychenko@magento.com> Date: Mon, 30 May 2016 16:16:16 +0300 Subject: [PATCH 025/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../DataProvider/Product/Form/Modifier/Composite.php | 2 +- .../adminhtml/web/js/components/bundle-option-qty.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php index 82eba7f655e..d61c7437513 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php @@ -120,7 +120,7 @@ class Composite extends AbstractModifier 'is_default' => ($productLink->getIsDefault()) ? '1' : '0', 'selection_price_value' => $productLink->getPrice(), 'selection_price_type' => $productLink->getPriceType(), - 'selection_qty' => (bool)$integerQty ? (int)$productLink->getQty() : $productLink->getQty(), + 'selection_qty' => (bool)$integerQty ? (string)(int)$productLink->getQty() : $productLink->getQty(), 'selection_can_change_qty' => $productLink->getCanChangeQuantity(), 'selection_qty_is_integer' => (bool)$integerQty, 'position' => $productLink->getPosition(), diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index 2ba8ddfc36c..16c187e0747 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -11,13 +11,23 @@ define([ return Abstract.extend({ defaults: { valueUpdate: 'input', - isInteger: true + isInteger: true, + links: { + isParent: '${ $.parentName }' + } }, /** * update event */ onUpdate: function () { + if (this.initialValue === this.value()) { + this.bubble('update', false); + this.validate(); + + return; + } + this.bubble('update', this.hasChanged()); this.validation['validate-number'] = true; this.validation['validate-digits'] = this.isInteger; -- GitLab From 95491dc1cc831a9380496074d95a9174806b5939 Mon Sep 17 00:00:00 2001 From: imelnychenko <imelnychenko@magento.com> Date: Mon, 30 May 2016 16:31:36 +0300 Subject: [PATCH 026/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Magento/Ui/view/base/web/js/form/element/abstract.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 7c2bbc65cbd..262d425bf46 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -316,7 +316,13 @@ define([ * @returns {Boolean} */ hasChanged: function () { - var notEqual = this.value() !== this.initialValue; + var notEqual; + + if (_.isObject(this.initialValue)) { + notEqual = false; + } else { + notEqual = this.value() !== this.initialValue; + } return !this.visible() ? false : notEqual; }, -- GitLab From bd3f67ff847b8dbaf25a13c3bc7b03e92b4a5e6a Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Mon, 30 May 2016 19:02:26 +0300 Subject: [PATCH 027/838] MAGETWO-52152: Import Custom options does not work --- .../Product/Form/Modifier/CustomOptions.php | 5 +- .../dynamic-rows-import-custom-options.js | 101 ++++++++++++------ .../web/js/dynamic-rows/dynamic-rows-grid.js | 44 +++++--- 3 files changed, 98 insertions(+), 52 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 43ad0e00180..6a1026a597d 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -356,7 +356,7 @@ class CustomOptions extends AbstractModifier 'collapsibleHeader' => true, 'sortOrder' => $sortOrder, 'dataProvider' => static::CUSTOM_OPTIONS_LISTING, - 'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], + 'imports' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], ], ], ], @@ -471,8 +471,7 @@ class CustomOptions extends AbstractModifier 'ns' => static::CUSTOM_OPTIONS_LISTING, 'render_url' => $this->urlBuilder->getUrl('mui/index/render'), 'realTimeLink' => true, - 'behaviourType' => 'edit', - 'externalFilterMode' => true, + 'externalFilterMode' => false, 'currentProductId' => $this->locator->getProduct()->getId(), 'dataLinks' => [ 'imports' => false, diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js index 0dea377e5d8..457dca40ffd 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js @@ -4,58 +4,69 @@ */ define([ - 'Magento_Ui/js/dynamic-rows/dynamic-rows', + 'Magento_Ui/js/dynamic-rows/dynamic-rows-grid', + 'underscore', 'mageUtils' -], function (DynamicRows, utils) { +], function (DynamicRows, _, utils) { 'use strict'; + var maxId = 0; + return DynamicRows.extend({ defaults: { - dataProvider: '', - insertData: [], - listens: { - 'insertData': 'processingInsertData' - } + mappingSettings: { + enabled: false, + distinct: false + }, + update: true, + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers + map: { + option_id: 'option_id' + }, + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers + identificationProperty: 'option_id', + identificationDRProperty: 'option_id' }, - /** - * Calls 'initObservable' of parent - * - * @returns {Object} Chainable. - */ - initObservable: function () { - this._super() - .observe([ - 'insertData' - ]); + /** @inheritdoc */ + initialize: function () { + this._super().initMaxId(); return this; }, - /** - * Parsed data - * - * @param {Array} data - array with data - * about selected records - */ + /** @inheritdoc */ processingInsertData: function (data) { - if (!data.length) { - return false; - } + var options = [], + currentOption; - data.each(function (options) { - options.options.each(function (option) { - var path = this.dataScope + '.' + this.index + '.' + this.recordIterator, - curOption = utils.copy(option); + if (!data) { + return; + } + data.each(function (item) { + if (!item.options) { + return; + } + item.options.each(function (option) { + currentOption = utils.copy(option); - if (curOption.hasOwnProperty('sort_order')) { - delete curOption['sort_order']; + if (currentOption.hasOwnProperty('sort_order')) { + delete currentOption['sort_order']; } + currentOption['option_id'] = ++maxId; + options.push(currentOption); + }); + }); - this.source.set(path, curOption); - this.addChild(curOption, false); - }, this); + if (!options || !options.length) { + return; + } + this.cacheGridData = options; + options.each(function (opt) { + this.mappingValue(opt); }, this); + + this.insertData([]); }, /** @@ -63,6 +74,26 @@ define([ */ clearDataProvider: function () { this.source.set(this.dataProvider, []); + }, + + /** @inheritdoc */ + processingAddChild: function (ctx, index, prop) { + if (ctx && !_.isNumber(ctx['option_id'])) { + ctx['option_id'] = ++maxId; + } + this._super(ctx, index, prop); + }, + + /** + * Stores max option_id value of the options from recordData once on initialization + * + */ + initMaxId: function () { + var data = this.recordData(); + + maxId = data && data.length ? ~~_.max(data, function (record) { + return ~~record['option_id']; + })['option_id'] : 0; } }); }); diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index bbc6033df00..29014c2967f 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -23,6 +23,10 @@ define([ listens: { 'insertData': 'processingInsertData', 'recordData': 'initElements setToInsertData' + }, + mappingSettings: { + enabled: true, + distinct: true } }, @@ -100,13 +104,19 @@ define([ * @param {String|Number} recordId */ deleteRecord: function (index, recordId) { - var data = this.getElementData(this.insertData(), recordId), - prop = this.map[this.identificationDRProperty]; + var data, + prop; this._super(); - this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) { - return ~~recordData[prop] === ~~data[prop]; - }, this)); + + if (this.links.insertData || this.exports.insertData) { + data = this.getElementData(this.insertData(), recordId); + prop = this.map[this.identificationDRProperty]; + + this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) { + return ~~recordData[prop] === ~~data[prop]; + }, this)); + } }, /** @@ -163,7 +173,7 @@ define([ var changes = [], tmpObj = {}; - if (data.length !== this.relatedData) { + if (data.length !== this.relatedData.length) { data.forEach(function (obj) { tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty]; @@ -210,21 +220,27 @@ define([ var obj = {}, tmpObj = {}; - _.each(this.map, function (prop, index) { - obj[index] = !_.isUndefined(data[prop]) ? data[prop] : ''; - }, this); + if (this.mappingSettings.enabled) { + _.each(this.map, function (prop, index) { + obj[index] = !_.isUndefined(data[prop]) ? data[prop] : ''; + }, this); + } else { + obj = data; + } - tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty]; + if (this.mappingSettings.distinct) { + tmpObj[this.identificationDRProperty] = obj[this.identificationDRProperty]; + + if (_.findWhere(this.recordData(), tmpObj)) { + return false; + } + } if (!obj.hasOwnProperty(this.positionProvider)) { this.setMaxPosition(); obj[this.positionProvider] = this.maxPosition; } - if (_.findWhere(this.recordData(), tmpObj)) { - return false; - } - this.source.set(this.dataScope + '.' + this.index + '.' + this.recordData().length, obj); }, -- GitLab From 6e5d2af850a85aa0c21291154de883e59465c6a2 Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@ebay.com> Date: Tue, 31 May 2016 10:47:29 +0300 Subject: [PATCH 028/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../view/adminhtml/web/js/components/bundle-option-qty.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index 16c187e0747..e3ddbfbd19e 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -11,10 +11,7 @@ define([ return Abstract.extend({ defaults: { valueUpdate: 'input', - isInteger: true, - links: { - isParent: '${ $.parentName }' - } + isInteger: true }, /** -- GitLab From f64b0c0e88a859bc9a4e39161e8f3f1f5456323d Mon Sep 17 00:00:00 2001 From: Gordon Lesti <info@gordonlesti.com> Date: Tue, 31 May 2016 11:25:44 +0200 Subject: [PATCH 029/838] replace fabpot/php-cs-fixer with friendsofphp/php-cs-fixer --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 83f10dac027..8e47935b9c3 100644 --- a/composer.json +++ b/composer.json @@ -69,7 +69,7 @@ "squizlabs/php_codesniffer": "1.5.3", "phpmd/phpmd": "@stable", "pdepend/pdepend": "2.2.2", - "fabpot/php-cs-fixer": "~1.2", + "friendsofphp/php-cs-fixer": "~1.2", "lusitanian/oauth": "~0.3 <=0.7.0", "sebastian/phpcpd": "2.0.0" }, -- GitLab From a17fbcd28f90960575fc39badf64c3088e7e1b0f Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 31 May 2016 12:54:23 +0300 Subject: [PATCH 030/838] MAGETWO-52152: Import Custom options does not work --- .../dynamic-rows-import-custom-options.js | 7 ++++++ .../web/js/dynamic-rows/dynamic-rows-grid.js | 24 +++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js index 457dca40ffd..18e206707e2 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js @@ -84,6 +84,13 @@ define([ this._super(ctx, index, prop); }, + /** + * Mutes parent method + */ + updateInsertData: function () { + return false; + }, + /** * Stores max option_id value of the options from recordData once on initialization * diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index 29014c2967f..de10c065d12 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -104,19 +104,23 @@ define([ * @param {String|Number} recordId */ deleteRecord: function (index, recordId) { - var data, - prop; - this._super(); - if (this.links.insertData || this.exports.insertData) { - data = this.getElementData(this.insertData(), recordId); - prop = this.map[this.identificationDRProperty]; + this.updateInsertData(recordId); + }, - this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) { - return ~~recordData[prop] === ~~data[prop]; - }, this)); - } + /** + * Updates insertData when record is deleted + * + * @param {String|Number} recordId + */ + updateInsertData: function (recordId) { + var data = this.getElementData(this.insertData(), recordId), + prop = this.map[this.identificationDRProperty]; + + this.insertData(_.reject(this.source.get(this.dataProvider), function (recordData) { + return ~~recordData[prop] === ~~data[prop]; + }, this)); }, /** -- GitLab From ebf4604c6ef8347699f3777f90d5d311b89e6e46 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 31 May 2016 13:40:42 +0300 Subject: [PATCH 031/838] MAGETWO-52152: Import Custom options does not work --- .../dynamic-rows-import-custom-options.js | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js index 18e206707e2..ddea2f9d338 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js @@ -10,7 +10,17 @@ define([ ], function (DynamicRows, _, utils) { 'use strict'; - var maxId = 0; + var maxId = 0, + + /** + * Stores max option_id value of the options from recordData once on initialization + * + */ + initMaxId = function (data) { + maxId = data && data.length ? ~~_.max(data, function (record) { + return ~~record['option_id']; + })['option_id'] : 0; + }; return DynamicRows.extend({ defaults: { @@ -19,18 +29,17 @@ define([ distinct: false }, update: true, - // jscs:disable requireCamelCaseOrUpperCaseIdentifiers map: { - option_id: 'option_id' + 'option_id': 'option_id' }, - // jscs:enable requireCamelCaseOrUpperCaseIdentifiers identificationProperty: 'option_id', identificationDRProperty: 'option_id' }, /** @inheritdoc */ initialize: function () { - this._super().initMaxId(); + this._super(); + initMaxId(this.recordData()); return this; }, @@ -58,7 +67,7 @@ define([ }); }); - if (!options || !options.length) { + if (!options.length) { return; } this.cacheGridData = options; @@ -89,18 +98,6 @@ define([ */ updateInsertData: function () { return false; - }, - - /** - * Stores max option_id value of the options from recordData once on initialization - * - */ - initMaxId: function () { - var data = this.recordData(); - - maxId = data && data.length ? ~~_.max(data, function (record) { - return ~~record['option_id']; - })['option_id'] : 0; } }); }); -- GitLab From 8a00888426e6528d1842efaa19938d197df01fef Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@ebay.com> Date: Tue, 31 May 2016 13:51:00 +0300 Subject: [PATCH 032/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Product/Form/Modifier/Composite.php | 2 +- .../web/js/components/bundle-option-qty.js | 25 +++++++++++-------- .../view/base/web/js/form/element/abstract.js | 8 +----- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php index d61c7437513..15631ff5291 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php @@ -120,7 +120,7 @@ class Composite extends AbstractModifier 'is_default' => ($productLink->getIsDefault()) ? '1' : '0', 'selection_price_value' => $productLink->getPrice(), 'selection_price_type' => $productLink->getPriceType(), - 'selection_qty' => (bool)$integerQty ? (string)(int)$productLink->getQty() : $productLink->getQty(), + 'selection_qty' => (bool)$integerQty ? (int)$productLink->getQty() : (float)$productLink->getQty(), 'selection_can_change_qty' => $productLink->getCanChangeQuantity(), 'selection_qty_is_integer' => (bool)$integerQty, 'position' => $productLink->getPosition(), diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index e3ddbfbd19e..b511e776c55 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -11,24 +11,29 @@ define([ return Abstract.extend({ defaults: { valueUpdate: 'input', - isInteger: true + isInteger: true, + validation: { + 'validate-number': true + } }, /** * update event */ onUpdate: function () { - if (this.initialValue === this.value()) { - this.bubble('update', false); - this.validate(); + this.validation['validate-digits'] = this.isInteger; + this._super(); + }, - return; - } + /** + * + * @returns {boolean} + */ + hasChanged: function () { + var notEqual = this.value() !== this.initialValue.toString(); - this.bubble('update', this.hasChanged()); - this.validation['validate-number'] = true; - this.validation['validate-digits'] = this.isInteger; - this.validate(); + return !this.visible() ? false : notEqual; } + }); }); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 262d425bf46..7c2bbc65cbd 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -316,13 +316,7 @@ define([ * @returns {Boolean} */ hasChanged: function () { - var notEqual; - - if (_.isObject(this.initialValue)) { - notEqual = false; - } else { - notEqual = this.value() !== this.initialValue; - } + var notEqual = this.value() !== this.initialValue; return !this.visible() ? false : notEqual; }, -- GitLab From eefee5a87f4ad5db690cb76b03fab6832476970c Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@ebay.com> Date: Tue, 31 May 2016 14:00:51 +0300 Subject: [PATCH 033/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../view/adminhtml/web/js/components/bundle-option-qty.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index b511e776c55..88c8ef51bf0 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -26,8 +26,9 @@ define([ }, /** + * Defines if value has changed. * - * @returns {boolean} + * @returns {Boolean} */ hasChanged: function () { var notEqual = this.value() !== this.initialValue.toString(); -- GitLab From 557b81bac1042dde006c76df8881a718a48b6648 Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@magento.com> Date: Tue, 31 May 2016 14:11:24 +0300 Subject: [PATCH 034/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../view/adminhtml/web/js/components/bundle-option-qty.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index 88c8ef51bf0..b5c1d61d41f 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -18,7 +18,7 @@ define([ }, /** - * update event + * @inheritdoc */ onUpdate: function () { this.validation['validate-digits'] = this.isInteger; @@ -26,9 +26,7 @@ define([ }, /** - * Defines if value has changed. - * - * @returns {Boolean} + * @inheritdoc */ hasChanged: function () { var notEqual = this.value() !== this.initialValue.toString(); -- GitLab From 9cd8155187c88e93f745e5dc8e9fdf0ecf65de8c Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 31 May 2016 15:14:07 +0300 Subject: [PATCH 035/838] MAGETWO-52152: Import Custom options does not work --- .../components/dynamic-rows-import-custom-options.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js index ddea2f9d338..7c5fd3bcb97 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js @@ -14,12 +14,14 @@ define([ /** * Stores max option_id value of the options from recordData once on initialization - * + * @param {Array} data - array with records data */ initMaxId = function (data) { - maxId = data && data.length ? ~~_.max(data, function (record) { - return ~~record['option_id']; - })['option_id'] : 0; + if (data && data.length) { + maxId = ~~_.max(data, function (record) { + return ~~record['option_id']; + })['option_id']; + } }; return DynamicRows.extend({ -- GitLab From 5ecc68ef6295ed3453931a4b9d285183324fb417 Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@magento.com> Date: Wed, 1 Jun 2016 11:42:01 +0300 Subject: [PATCH 036/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Product/Form/Modifier/BundlePanel.php | 1 + .../web/js/components/bundle-action-delete.js | 21 +++++++++++++++++++ .../web/js/components/bundle-option-qty.js | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index f2a2cb4ab7c..8459c4d1f6f 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -671,6 +671,7 @@ class BundlePanel extends AbstractModifier 'arguments' => [ 'data' => [ 'config' => [ + 'component' => 'Magento_Bundle/js/components/bundle-action-delete', 'componentType' => 'actionDelete', 'dataType' => Form\Element\DataType\Text::NAME, 'label' => '', diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js new file mode 100644 index 00000000000..f551ba5bb64 --- /dev/null +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js @@ -0,0 +1,21 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Ui/js/form/element/abstract' +], function (Abstract) { + 'use strict'; + + return Abstract.extend({ + /** + * @inheritdoc + */ + hasChanged: function () { + + return false; + } + + }); +}); diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index b5c1d61d41f..7a8e13320cc 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -29,7 +29,7 @@ define([ * @inheritdoc */ hasChanged: function () { - var notEqual = this.value() !== this.initialValue.toString(); + var notEqual = this.value().toString() !== this.initialValue.toString(); return !this.visible() ? false : notEqual; } -- GitLab From e6cb07cd26b0291a2c2426c0c95b8e20b614d2f4 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 1 Jun 2016 16:35:04 +0300 Subject: [PATCH 037/838] MAGETWO-52788: [UI Component] Dynamic Rows: support status being changed - fix static tests --- .../web/js/dynamic-rows/dynamic-rows-grid.js | 2 +- .../base/web/js/dynamic-rows/dynamic-rows.js | 35 +++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index 16ce4e1620f..a3f78d9fcb8 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -46,7 +46,7 @@ define([ setToInsertData: function () { var insertData = [], obj; - + if (this.recordData().length && !this.update) { this.recordData.each(function (recordData) { obj = {}; diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 1f174c7fd04..7c312d07452 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -14,6 +14,21 @@ define([ ], function (ko, utils, _, layout, uiCollection, registry, $t) { 'use strict'; + /** + * Checks value type and cast to boolean if needed + * + * @param {*} value + * + * @returns {Boolean|*} casted or origin value + */ + function castValue(value) { + if (_.isUndefined(value) || value === '' || _.isNull(value)) { + return false; + } + + return value; + } + /** * Compares arrays. * @@ -30,7 +45,7 @@ define([ return false; } - /*eslint-disable max-depth, eqeqeq */ + /*eslint-disable max-depth, eqeqeq, no-use-before-define */ for (index; index < length; index++) { if (_.isArray(base[index]) && _.isArray(current[index])) { if (!compareArrays(base[index], current[index])) { @@ -43,7 +58,7 @@ define([ } else if (castValue(base[index]) != castValue(current[index])) { return false; } - }/*eslint-enable max-depth, eqeqeq */ + }/*eslint-enable max-depth, eqeqeq, no-use-before-define */ return true; } @@ -78,21 +93,6 @@ define([ return true; } - /** - * Checks value type and cast to boolean if needed - * - * @param {*} value - * - * @returns {Boolean|*} casted or origin value - */ - function castValue(value) { - if (_.isUndefined(value) || value === '' || _.isNull(value)) { - return false; - } - - return value; - } - return uiCollection.extend({ defaults: { defaultRecord: false, @@ -244,7 +244,6 @@ define([ this.isDefaultState(result); }, - /** * Inits default component state * -- GitLab From 6264b0935066cf3dd2531de4764c8fa9df2fdd68 Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@magento.com> Date: Thu, 2 Jun 2016 12:59:48 +0300 Subject: [PATCH 038/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php | 2 +- .../view/adminhtml/web/js/components/bundle-action-delete.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php index 15631ff5291..d671d0bf75a 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php @@ -120,7 +120,7 @@ class Composite extends AbstractModifier 'is_default' => ($productLink->getIsDefault()) ? '1' : '0', 'selection_price_value' => $productLink->getPrice(), 'selection_price_type' => $productLink->getPriceType(), - 'selection_qty' => (bool)$integerQty ? (int)$productLink->getQty() : (float)$productLink->getQty(), + 'selection_qty' => $integerQty ? (int)$productLink->getQty() : (float)$productLink->getQty(), 'selection_can_change_qty' => $productLink->getCanChangeQuantity(), 'selection_qty_is_integer' => (bool)$integerQty, 'position' => $productLink->getPosition(), diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js index f551ba5bb64..502056aeba3 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js @@ -13,7 +13,6 @@ define([ * @inheritdoc */ hasChanged: function () { - return false; } -- GitLab From 6cdccadeab9380716e1424ec5781ace7c6009d51 Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@magento.com> Date: Thu, 2 Jun 2016 18:00:58 +0300 Subject: [PATCH 039/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Product/Form/Modifier/BundlePanel.php | 1 - .../web/js/components/bundle-action-delete.js | 20 ------------------- .../web/js/components/bundle-option-qty.js | 2 +- 3 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index 8459c4d1f6f..f2a2cb4ab7c 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -671,7 +671,6 @@ class BundlePanel extends AbstractModifier 'arguments' => [ 'data' => [ 'config' => [ - 'component' => 'Magento_Bundle/js/components/bundle-action-delete', 'componentType' => 'actionDelete', 'dataType' => Form\Element\DataType\Text::NAME, 'label' => '', diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js deleted file mode 100644 index 502056aeba3..00000000000 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-action-delete.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -define([ - 'Magento_Ui/js/form/element/abstract' -], function (Abstract) { - 'use strict'; - - return Abstract.extend({ - /** - * @inheritdoc - */ - hasChanged: function () { - return false; - } - - }); -}); diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js index 7a8e13320cc..b5c1d61d41f 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js @@ -29,7 +29,7 @@ define([ * @inheritdoc */ hasChanged: function () { - var notEqual = this.value().toString() !== this.initialValue.toString(); + var notEqual = this.value() !== this.initialValue.toString(); return !this.visible() ? false : notEqual; } -- GitLab From 666abb85916b2094975f2b38f1c2875041530f05 Mon Sep 17 00:00:00 2001 From: Ihor Melnychenko <imelnychenko@magento.com> Date: Fri, 3 Jun 2016 12:52:17 +0300 Subject: [PATCH 040/838] MAGETWO-53455: Field "Default Quantity" on bundle product doesn't trigger update event --- .../Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php index d671d0bf75a..d5383473edf 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php @@ -120,7 +120,7 @@ class Composite extends AbstractModifier 'is_default' => ($productLink->getIsDefault()) ? '1' : '0', 'selection_price_value' => $productLink->getPrice(), 'selection_price_type' => $productLink->getPriceType(), - 'selection_qty' => $integerQty ? (int)$productLink->getQty() : (float)$productLink->getQty(), + 'selection_qty' => $integerQty ? (int)$productLink->getQty() : $productLink->getQty(), 'selection_can_change_qty' => $productLink->getCanChangeQuantity(), 'selection_qty_is_integer' => (bool)$integerQty, 'position' => $productLink->getPosition(), -- GitLab From 89ce4147205cd21bf87b0a9ddf746ea78f56c756 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 3 Jun 2016 13:29:59 +0300 Subject: [PATCH 041/838] MAGETWO-53852: Event update works incorrectly --- .../adminhtml/web/template/dynamic-rows/grid.html | 2 +- .../Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 11 +++++++++++ .../Ui/view/base/web/js/form/components/fieldset.js | 1 + .../templates/dynamic-rows/templates/collapsible.html | 2 +- .../web/templates/dynamic-rows/templates/default.html | 2 +- .../web/templates/dynamic-rows/templates/grid.html | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html index 6e24ee96a62..f3642eedf6f 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html +++ b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html @@ -34,7 +34,7 @@ </label> <div class="admin__field-control" data-role="grid-wrapper"> - <div class="admin__control-table-pagination" visible="!!$data.recordData().length"> + <div class="admin__control-table-pagination" visible="!!element.getRecordCount()"> <div class="admin__data-grid-pager"> <button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button> <input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage"> diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 7c312d07452..62aef71a4e4 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -420,6 +420,17 @@ define([ return this.relatedData.slice(this.startIndex, this.startIndex + this.pageSize); }, + /** + * Get record count with filtered delete property. + * + * @returns {Number} count + */ + getRecordCount: function () { + return _.filter(this.recordData(), function (record) { + return record[this.deleteProperty] !== this.deleteValue; + }, this).length; + }, + /** * Get number of columns * diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js index c400fcac43a..b7031f1df85 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js @@ -85,6 +85,7 @@ define([ hasChanged = _.some(this.delegate('hasChanged')); } + this.bubble('update', hasChanged); this.changed(hasChanged); }, diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html index 84a41142548..bfe935086e5 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html @@ -10,7 +10,7 @@ </label> <div class="admin__field-control" data-role="grid-wrapper"> - <div class="admin__control-table-pagination" visible="!!$data.recordData().length"> + <div class="admin__control-table-pagination" visible="!!element.getRecordCount()"> <div class="admin__data-grid-pager"> <button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button> <input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage"> diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index b5f4541b648..52e8988e66d 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -60,7 +60,7 @@ <span text="addButtonLabel"/> </button> - <div class="admin__control-table-pagination" visible="!!$data.recordData().length && (pages() > 1)"> + <div class="admin__control-table-pagination" visible="!!element.getRecordCount() && (pages() > 1)"> <div class="admin__data-grid-pager"> <button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button> <input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage"> diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html index 13f1bed36d2..450a49ba040 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html @@ -15,7 +15,7 @@ </label> <div class="admin__field-control" data-role="grid-wrapper"> - <div class="admin__control-table-pagination" visible="!!$data.recordData().length"> + <div class="admin__control-table-pagination" visible="!!element.getRecordCount()"> <div class="admin__data-grid-pager"> <button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button> <input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage"> -- GitLab From 3e7c489e776d2199ed6bfca679fec5243470a3d2 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Mon, 6 Jun 2016 14:20:28 +0300 Subject: [PATCH 042/838] MAGETWO-53852: Event update works incorrectly --- .../js/components/custom-options-price-type.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js index 107fa05af1d..49fb47b0a60 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js @@ -15,7 +15,10 @@ define([ isFiltered: null, defaultOptions: null, filteredOptions: null, - bannedOptions: [] + bannedOptions: [], + listens: { + 'visible': 'updateValue' + } }, /** @@ -71,6 +74,18 @@ define([ } return this.filteredOptions; + }, + + /** + * Clears value of hidden select + * @param {Boolean} visible + */ + updateValue: function (visible) { + if (visible) { + this.updateOptions(); + } else { + this.value(null); + } } }); }); -- GitLab From 1a004029ec5f4060d9312bd5dcd6431b66f4f900 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 7 Jun 2016 10:00:28 +0300 Subject: [PATCH 043/838] MAGETWO-53852: Event update works incorrectly --- .../Ui/view/base/web/js/dynamic-rows/dnd.js | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js index 594e300145b..2e0cbff3c21 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dnd.js @@ -58,8 +58,12 @@ define([ recordsCache: [], draggableElement: {}, draggableElementClass: '_dragged', + elemPositions: [], listens: { '${ $.recordsProvider }:elems': 'setCacheRecords' + }, + modules: { + parentComponent: '${ $.recordsProvider }' } }, @@ -192,6 +196,8 @@ define([ drEl.depElement = this.getDepElement(drEl.instance, positionY, this.draggableElement.originRow); + drEl.instance.remove(); + if (drEl.depElement) { depElementCtx = this.getRecord(drEl.depElement.elem[0]); drEl.depElement.elem.removeClass(drEl.depElement.className); @@ -211,7 +217,6 @@ define([ this.body.unbind('mouseup', this.mouseupHandler); } - drEl.instance.remove(); this.draggableElement = {}; }, @@ -225,11 +230,34 @@ define([ setPosition: function (depElem, depElementCtx, dragData) { var depElemPosition = ~~depElementCtx.position; + this.cacheElementsPosition(); + if (dragData.depElement.insert === 'after') { dragData.instanceCtx.position = depElemPosition + 1; } else if (dragData.depElement.insert === 'before') { dragData.instanceCtx.position = depElemPosition; } + + this.normalizePositions(); + }, + + /** + * Saves elements position from current elements + */ + cacheElementsPosition: function () { + this.elemPositions = []; + this.parentComponent().elems.each(function (elem) { + this.elemPositions.push(elem.position); + }, this); + }, + + /** + * Normalize position, uses start elements position + */ + normalizePositions: function () { + this.parentComponent().elems.each(function (item, index) { + item.position = this.elemPositions[index]; + }, this); }, /** -- GitLab From 4c74b6112bc5119a62045469ff36f769dc679181 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 8 Jun 2016 10:32:46 +0300 Subject: [PATCH 044/838] MAGETWO-53852: Event update works incorrectly --- .../view/base/ui_component/etc/definition.xml | 3 +- .../base/web/js/dynamic-rows/action-delete.js | 28 +++++++++++++++++++ .../base/web/js/dynamic-rows/dynamic-rows.js | 24 ++++++++++++++++ .../dynamic-rows/cells/action-delete.html | 2 +- 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Ui/view/base/web/js/dynamic-rows/action-delete.js diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml index 105f6dd8dcd..7426ce9ddf2 100755 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml @@ -211,8 +211,7 @@ <actionDelete class="Magento\Ui\Component\Form\Element\ActionDelete"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> - <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item> - <item name="elementTmpl" xsi:type="string">ui/dynamic-rows/cells/action-delete</item> + <item name="component" xsi:type="string">Magento_Ui/js/dynamic-rows/action-delete</item> <item name="template" xsi:type="string">ui/dynamic-rows/cells/action-delete</item> </item> </argument> diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/action-delete.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/action-delete.js new file mode 100644 index 00000000000..6643639f599 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/action-delete.js @@ -0,0 +1,28 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Ui/js/form/element/abstract' +], function (Abstract) { + 'use strict'; + + return Abstract.extend({ + defaults: { + links: { + value: false + } + }, + + /** + * Delete record handler. + * + * @param {Number} index + * @param {Number} id + */ + deleteRecord: function (index, id) { + this.bubble('deleteRecord', index, id); + } + }); +}); diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 62aef71a4e4..5abfdf6f5a7 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -164,6 +164,7 @@ define([ * @returns {Object} Chainable. */ initialize: function () { + _.bindAll(this, 'processingDeleteRecord'); this._super() .initDefaultState() .initChildren() @@ -199,6 +200,29 @@ define([ return this; }, + /** + * @inheritdoc + */ + initElement: function (elem) { + this._super(); + elem.on({ + 'deleteRecord': this.processingDeleteRecord + }); + + return this; + }, + + /** + * @inheritdoc + */ + bubble: function (event) { + if (event === 'deleteRecord') { + return false; + } + + return this._super(); + }, + /** * Inits DND module * diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html index a8a77d593fe..7d4c5373aed 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html @@ -7,7 +7,7 @@ <button class="action-delete" attr="{'data-action': 'remove_row'}" data-bind=" - click: function(){ $parent.processingDeleteRecord($record().index, $record().recordId); }, + click: $data.deleteRecord.bind($data, $record().index, $record().recordId), attr: { title: $parent.deleteButtonLabel } -- GitLab From 29abd2f8babc1763e523b77d7a9e2560835163f1 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 8 Jun 2016 15:09:18 +0300 Subject: [PATCH 045/838] MAGETWO-53161: Tooltip click does not prevent anchor event --- .../Ui/view/base/web/js/lib/knockout/bindings/tooltip.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js index 819058ff7a8..6040b1efa7a 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/tooltip.js @@ -599,6 +599,8 @@ define([ } tooltip.setContent.apply(null, arguments); + + return false; }, /** -- GitLab From dac65e5a5b86a7880decb4a696f7bc916fdd23d0 Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Thu, 9 Jun 2016 14:31:34 +0300 Subject: [PATCH 046/838] MAGETWO-52309: Configurable Product. Price should not be sent to server while saving. --- .../Form/Modifier/ConfigurablePrice.php | 8 +-- .../web/js/components/price-configurable.js | 54 +++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php index 533c3367fd8..0e7d82f9083 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurablePrice.php @@ -61,10 +61,8 @@ class ConfigurablePrice extends AbstractModifier 'arguments' => [ 'data' => [ 'config' => [ - 'imports' => [ - 'disabled' => '!ns = ${ $.ns }, index = ' - . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', - ], + 'component' => 'Magento_ConfigurableProduct/js/' . + 'components/price-configurable' ], ], ], @@ -79,8 +77,6 @@ class ConfigurablePrice extends AbstractModifier ? ['visible' => 0, 'disabled' => 1] : [ 'imports' => [ - 'disabled' => '!ns = ${ $.ns }, index = ' - . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', 'visible' => 'ns = ${ $.ns }, index = ' . ConfigurablePanel::CONFIGURABLE_MATRIX . ':isEmpty', ] diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js new file mode 100644 index 00000000000..70d68ed018b --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js @@ -0,0 +1,54 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'underscore', + 'uiRegistry', + 'Magento_Ui/js/form/element/abstract' +], function (_, registry, Abstract) { + 'use strict'; + + return Abstract.extend({ + defaults: { + listens: { + isConfigurable: 'handlePriceVisibility' + }, + imports: { + isConfigurable: '!ns = ${ $.ns }, index = configurable-matrix:isEmpty' + }, + modules: { + createConfigurableButton: '${$.createConfigurableButton}' + } + }, + + /** + * Invokes initialize method of parent class, + * contains initialization logic + */ + initialize: function () { + this._super(); + + return this; + }, + + /** + * Calls 'initObservable' of parent + * + * @returns {Object} Chainable. + */ + initObservable: function () { + this._super() + .observe(['content']); + + return this; + }, + + handlePriceVisibility: function (isConfigurable) { + if (isConfigurable) { + this.disable(); + this.clear(); + } + } + }); +}); \ No newline at end of file -- GitLab From f0a89eb2801f9ac407d9cc0a4bfc7677c3ea8798 Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Thu, 9 Jun 2016 14:49:00 +0300 Subject: [PATCH 047/838] MAGETWO-52309: Configurable Product. Price should not be sent to server while saving. - Fixed JavaScript static test --- .../adminhtml/web/js/components/price-configurable.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js index 70d68ed018b..4bdeb678cd9 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js @@ -12,7 +12,7 @@ define([ return Abstract.extend({ defaults: { listens: { - isConfigurable: 'handlePriceVisibility' + isConfigurable: 'handlePriceValue' }, imports: { isConfigurable: '!ns = ${ $.ns }, index = configurable-matrix:isEmpty' @@ -44,11 +44,16 @@ define([ return this; }, - handlePriceVisibility: function (isConfigurable) { + /** + * Disable and clear price if product type changed to configurable + * + * @param {String} isConfigurable + */ + handlePriceValue: function (isConfigurable) { if (isConfigurable) { this.disable(); this.clear(); } } }); -}); \ No newline at end of file +}); -- GitLab From ff31e19e3fbf7c9c57c0f34cce6d765476af36cb Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Sat, 11 Jun 2016 17:08:56 +0300 Subject: [PATCH 048/838] MAGETWO-51616: Admin data grids search values aren't trimmed --- app/code/Magento/Ui/view/base/web/js/grid/search/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/search/search.js b/app/code/Magento/Ui/view/base/web/js/grid/search/search.js index 5760866ec33..16b850e7641 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/search/search.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/search/search.js @@ -105,7 +105,7 @@ define([ apply: function (value) { value = value || this.inputValue; - this.value = this.inputValue = value; + this.value = this.inputValue = value.trim(); return this; }, -- GitLab From 7c0f589079a87f6bae01ca6faa836be3690311fe Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Tue, 14 Jun 2016 08:35:45 +0300 Subject: [PATCH 049/838] MAGETWO-52309: Configurable Product. Price should not be sent to server while saving. - Fixed bug --- .../view/adminhtml/web/js/components/price-configurable.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js index 4bdeb678cd9..9a676d660c7 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/price-configurable.js @@ -53,6 +53,8 @@ define([ if (isConfigurable) { this.disable(); this.clear(); + } else { + this.enable(); } } }); -- GitLab From a61d4966aca254fc53cd3a751784c69a67f2969e Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 17 Jun 2016 13:11:02 +0300 Subject: [PATCH 050/838] MAGETWO-46843: Inline translation unavailable for some templates in UI module --- .../template/dynamic-rows/cells/action-delete.html | 2 +- .../adminhtml/web/template/dynamic-rows/grid.html | 6 +++--- .../web/template/form/element/action-delete.html | 2 +- .../templates/dynamic-rows/cells/action-delete.html | 2 +- .../dynamic-rows/templates/collapsible.html | 10 +++++----- .../templates/dynamic-rows/templates/default.html | 6 +++--- .../web/templates/dynamic-rows/templates/grid.html | 6 +++--- .../templates/form/element/uploader/uploader.html | 4 ++-- .../Ui/view/base/web/templates/form/field.html | 4 ++-- .../Ui/view/base/web/templates/form/fieldset.html | 2 +- .../view/base/web/templates/grid/columns/text.html | 2 +- .../base/web/templates/grid/controls/columns.html | 2 +- .../web/templates/grid/filters/elements/group.html | 2 +- .../templates/grid/filters/elements/ui-select.html | 12 ++++-------- .../view/base/web/templates/grid/filters/field.html | 2 +- .../Ui/view/base/web/templates/group/group.html | 2 +- .../web/templates/form/element/helper/tooltip.html | 3 +-- .../Ui/view/frontend/web/templates/form/field.html | 2 +- .../Ui/view/frontend/web/templates/group/group.html | 2 +- 19 files changed, 34 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/cells/action-delete.html b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/cells/action-delete.html index 117eee7e69f..44c460825b4 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/cells/action-delete.html +++ b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/cells/action-delete.html @@ -11,5 +11,5 @@ title: $parent.deleteButtonLabel } "> - <span data-bind="text: $parent.deleteButtonLabel"></span> + <span translate="$parent.deleteButtonLabel"></span> </button> diff --git a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html index 6e24ee96a62..63a3196ff33 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html +++ b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html @@ -16,7 +16,7 @@ class="action-secondary" type="button" click="processingAddChild.bind($data, false, false, false)"> - <span text="addButtonLabel"/> + <span translate="addButtonLabel"/> </button> </div> @@ -30,7 +30,7 @@ css="element.setClasses(element)" attr="'data-index': index"> <label if="element.label" class="admin__field-label" attr="for: element.uid"> - <span text="element.label"/> + <span translate="element.label"/> </label> <div class="admin__field-control" data-role="grid-wrapper"> @@ -51,7 +51,7 @@ <th repeat="foreach: labels, item: '$label'" class="data-grid-th" - text="$label().label" + translate="$label().label" visible="$label().visible" disable="$label().disabled" css="setClasses($label())"> diff --git a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/action-delete.html b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/action-delete.html index 9f223325939..13445314101 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/action-delete.html +++ b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/action-delete.html @@ -12,5 +12,5 @@ title: $parent.deleteButtonLabel } "> - <span data-bind="text: $parent.deleteButtonLabel"></span> + <span translate="$parent.deleteButtonLabel"></span> </button> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html index a8a77d593fe..854705a75d5 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/cells/action-delete.html @@ -12,5 +12,5 @@ title: $parent.deleteButtonLabel } "> - <span data-bind="text: $parent.deleteButtonLabel"></span> + <span translate="$parent.deleteButtonLabel"></span> </button> \ No newline at end of file diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html index 84a41142548..df776f59e7b 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html @@ -6,7 +6,7 @@ --> <div class="admin__field" css="element.setClasses(element)"> <label if="element.label" class="admin__field-label" attr="for: element.uid"> - <span text="element.label"/> + <span translate="element.label"/> </label> <div class="admin__field-control" data-role="grid-wrapper"> @@ -22,7 +22,7 @@ <thead if="element.columnsHeader"> <tr data-bind="foreach: {data: labels, as: 'label'}"> - <th text="label.config.label" + <th translate="label.config.label" css="item.columnsHeaderClasses"> </th> </tr> @@ -39,7 +39,7 @@ <render args="name: $parents[1].dndConfig.template, data: $parents[1].dnd" if="$parents[1].dndConfig.enabled" /> - <span text="$parent.getLabel(elem)" /> + <span translate="$parent.getLabel(elem)" /> </div> <button class="action-delete" @@ -48,7 +48,7 @@ click="function(){ $parents[1].deleteRecord($parent.index, $parent.recordId) }"> - <span text="'Delete'"/> + <span translate="'Delete'"/> </button> </div> @@ -66,7 +66,7 @@ <button attr="{disabled: disabled}" type="button" click="addChild.bind($data, false, false)"> - <span text="addButtonLabel"/> + <span translate="addButtonLabel"/> </button> </div> </div> diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index b69c6b0de65..55ecfedb1af 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -6,7 +6,7 @@ --> <div class="admin__field" visible="visible" disable="disabled" css="element.setClasses(element)"> <label if="element.label" class="admin__field-label" attr="for: element.uid"> - <span text="element.label"/> + <span translate="element.label"/> </label> <div class="admin__field-control" data-role="grid-wrapper" attr="'data-index': index"> @@ -24,7 +24,7 @@ <tr> <th if="dndConfig.enabled"/> <th repeat="foreach: labels, item: '$label'" - text="$label().label" + translate="$label().label" css="setClasses($label())" visible="$label().visible" disable="$label().disabled" @@ -56,7 +56,7 @@ attr="{disabled: disabled, 'data-action': 'add_new_row'}" type="button" click="processingAddChild.bind($data, false, false, false)"> - <span text="addButtonLabel"/> + <span translate="addButtonLabel"/> </button> <div class="admin__control-table-pagination" visible="!!$data.recordData().length && (pages() > 1)"> diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html index 13f1bed36d2..3a5b8ad4631 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html @@ -11,7 +11,7 @@ css="element.setClasses(element)" attr="'data-index': index"> <label if="element.label" class="admin__field-label" attr="for: element.uid"> - <span text="element.label"/> + <span translate="element.label"/> </label> <div class="admin__field-control" data-role="grid-wrapper"> @@ -40,7 +40,7 @@ <th repeat="foreach: labels, item: '$label'" class="data-grid-th" - text="$label().label" + translate="$label().label" visible="$label().visible" disable="$label().disabled" css="$label().columnsHeaderClasses"> @@ -73,7 +73,7 @@ <button attr="{disabled: disabled}" type="button" click="addChild.bind($data, false, false)"> - <span text="addButtonLabel"/> + <span translate="addButtonLabel"/> </button> </div> <render args="fallbackResetTpl" if="$data.showFallbackReset && $data.isDifferedFromDefault"/> diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html b/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html index 7415b4e6c33..84381319ed2 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html @@ -6,7 +6,7 @@ --> <div class="admin__field" visible="visible" css="$data.additionalClasses"> <label class="admin__field-label" if="$data.label" attr="for: uid"> - <span text="label" attr="'data-config-scope': $data.scopeLabel"/> + <span translate="label" attr="'data-config-scope': $data.scopeLabel"/> </label> <div class="admin__field-control" css="'_with-tooltip': $data.tooltip"> @@ -22,7 +22,7 @@ <render args="tooltipTpl" if="$data.tooltip"/> <div class="admin__field-note" if="$data.notice" attr="id: noticeId"> - <span html="notice"/> + <span translate="notice"/> </div> <label class="admin__field-error" if="error" attr="for: uid" text="error"/> 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 60f902a42d9..adc9814a91d 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 @@ -9,7 +9,7 @@ css="$data.additionalClasses" attr="'data-index': index"> <label class="admin__field-label" if="$data.label" visible="$data.labelVisible" attr="for: uid"> - <span text="label" attr="'data-config-scope': $data.scopeLabel"/> + <span translate="label" attr="'data-config-scope': $data.scopeLabel"/> </label> <div class="admin__field-control" css="'_with-tooltip': $data.tooltip, '_with-reset': $data.showFallbackReset && $data.isDifferedFromDefault"> @@ -33,7 +33,7 @@ <label class="admin__field-error" if="error" attr="for: uid" text="error"/> <div class="admin__field-note" if="$data.notice" attr="id: noticeId"> - <span text="notice"/> + <span translate="notice"/> </div> <div class="admin__additional-info" if="$data.additionalInfo" html="$data.additionalInfo"></div> diff --git a/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html index aeb93f48ff6..7ff3a9bbe16 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html @@ -19,7 +19,7 @@ '_changed': changed, '_loading': loading, '_error': error"> - <span text="label"/> + <span translate="label"/> <span class="admin__page-nav-item-messages"> <span class="admin__page-nav-item-message _changed"> <span class="admin__page-nav-item-message-icon"></span> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html index ce901505153..b045149dda5 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/text.html @@ -10,5 +10,5 @@ _draggable: draggable, _ascend: sorting === 'asc', _descend: sorting === 'desc'"> - <span class="data-grid-cell-content" text="label"/> + <span class="data-grid-cell-content" translate="label"/> </th> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html b/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html index c14044de44e..2335247c5ad 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/controls/columns.html @@ -16,7 +16,7 @@ disable="isDisabled($col())" ko-checked="$col().visible" attr="id: ++ko.uid"/> - <label class="admin__field-label" text="$col().label" attr="for: ko.uid"/> + <label class="admin__field-label" translate="$col().label" attr="for: ko.uid"/> </div> </div> <div class="admin__action-dropdown-menu-footer"> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html index d768bd8033c..7d89f3dbecf 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/group.html @@ -5,6 +5,6 @@ */ --> <legend class="admin__form-field-legend"> - <span text="label"/> + <span translate="label"/> </legend> <div class="admin__form-field" outereach="elems" render=""/> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html index 326a9d7ee4a..a913d27c8aa 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html @@ -10,7 +10,7 @@ class="admin__form-field-label" data-bind="attr: {for: uid} "> - <span data-bind="text: label"></span> + <span translate="label"></span> </label> <!-- /ko --> <div @@ -60,7 +60,7 @@ <div class="admin__action-multiselect-text" data-bind=" visible: !hasData(), - text: selectedPlaceholders.defaultPlaceholder + i18n: selectedPlaceholders.defaultPlaceholder "> </div> <!-- ko foreach: { data: getSelected(), as: 'option'} --> @@ -74,11 +74,7 @@ tabindex="-1" data-bind="click: $parent.removeSelected.bind($parent, value) "> - <span - class="action-close-text" - data-bind="text: 'Close' - "> - </span> + <span class="action-close-text" translate="'Close'"></span> </button> </span> <!-- /ko --> @@ -177,7 +173,7 @@ data-action="close-advanced-select" type="button" data-bind="click: outerClick"> - <span data-bind="text: closeBtnLabel"></span> + <span translate="closeBtnLabel"></span> </button> </div> <!-- /ko --> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/field.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/field.html index 1d5290bc6cc..6fa5df5497e 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/field.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/field.html @@ -5,6 +5,6 @@ */ --> <label class="admin__form-field-label" attr="for: uid"> - <span text="label"/> + <span translate="label"/> </label> <div class="admin__form-field-control" render="elementTmpl"/> diff --git a/app/code/Magento/Ui/view/base/web/templates/group/group.html b/app/code/Magento/Ui/view/base/web/templates/group/group.html index de4b9cc332e..ed1c9efd2b0 100644 --- a/app/code/Magento/Ui/view/base/web/templates/group/group.html +++ b/app/code/Magento/Ui/view/base/web/templates/group/group.html @@ -9,7 +9,7 @@ css="_required: required" attr="'data-index': index"> <legend class="admin__field-label" if="showLabel"> - <span text="label" attr="'data-config-scope': $data.scopeLabel"/> + <span translate="label" attr="'data-config-scope': $data.scopeLabel"/> </legend> <div class="admin__field-control" css="$data.additionalClasses"> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html index 8cb1cf0eae7..393989112c9 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html @@ -21,7 +21,6 @@ <!-- /ko --> <div class="field-tooltip-content" - data-target="dropdown"> - <!-- ko text: tooltip.description --><!-- /ko --> + data-target="dropdown" translate="tooltip.description"> </div> </div> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html index 38d868a0f61..f3be62f116b 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html @@ -8,7 +8,7 @@ <label class="label" data-bind="attr: { for: element.uid }"> <!-- ko if: element.label --> - <span data-bind="text: element.label"></span> + <span translate="element.label"></span> <!-- /ko --> </label> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/group/group.html b/app/code/Magento/Ui/view/frontend/web/templates/group/group.html index 214fc6190ec..8475a3e137b 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/group/group.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/group/group.html @@ -6,7 +6,7 @@ --> <fieldset class="field" data-bind="css: additionalClasses"> <legend class="label"> - <span data-bind="text: element.label"></span> + <span translate="element.label"></span> </legend> <div class="control"> <!-- ko foreach: { data: elems, as: 'element' } --> -- GitLab From 04474dd9e323ef1dd8cefa7990c0b9c0c1fa3a86 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 21 Jun 2016 12:50:06 +0300 Subject: [PATCH 051/838] MAGETWO-53852: Event update works incorrectly --- .../web/js/dynamic-rows/dynamic-rows-grid.js | 2 +- .../base/web/js/dynamic-rows/dynamic-rows.js | 141 +++++++++++++----- 2 files changed, 108 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js index c280bbe658c..de10c065d12 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js @@ -22,7 +22,7 @@ define([ identificationDRProperty: 'id', listens: { 'insertData': 'processingInsertData', - 'recordData': 'initElements setToInsertData checkDefaultState' + 'recordData': 'initElements setToInsertData' }, mappingSettings: { enabled: true, diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 5abfdf6f5a7..fe5b5cee586 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -116,6 +116,7 @@ define([ showSpinner: true, isDifferedFromDefault: false, defaultState: [], + changed: false, isDefaultState: true, fallbackResetTpl: 'ui/form/element/helper/fallback-reset-link', dndConfig: { @@ -141,10 +142,10 @@ define([ disabled: 'setDisabled', childTemplate: 'initHeader', recordTemplate: 'onUpdateRecordTemplate', - recordData: 'setDifferedFromDefault parsePagesData checkDefaultState', + recordData: 'setDifferedFromDefault parsePagesData', currentPage: 'changePage', elems: 'checkSpinner', - isDefaultState: 'updateTrigger' + changed: 'updateTrigger' }, modules: { dnd: '${ $.dndConfig.name }' @@ -164,15 +165,26 @@ define([ * @returns {Object} Chainable. */ initialize: function () { - _.bindAll(this, 'processingDeleteRecord'); + _.bindAll(this, 'processingDeleteRecord', 'onChildrenUpdate'); this._super() - .initDefaultState() .initChildren() .initDnd() .setColumnsHeaderListener() .initDefaultRecord() .checkSpinner(); + if (_.isArray(this.recordData())) { + this.recordData.each(function (data, index) { + this.source.set(this.dataScope + '.' + this.index + '.' + index + '.initialize', true); + }, this); + + } + + if (this.name === 'product_form.product_form.related.related.related') { + debugger; + } + this.on('recordData', this.checkDefaultState.bind(this)); + return this; }, @@ -194,7 +206,7 @@ define([ 'labels', 'showSpinner', 'isDifferedFromDefault', - 'isDefaultState' + 'changed' ]); return this; @@ -206,12 +218,78 @@ define([ initElement: function (elem) { this._super(); elem.on({ - 'deleteRecord': this.processingDeleteRecord + 'deleteRecord': function(index, id){ + this.getDefaultState(); + this.processingDeleteRecord(index, id); + this.changed(!compareArrays(this.defaultState, this.recordData())); + }.bind(this), + 'update': function (state) { + this.onChildrenUpdate(state); + }.bind(this) }); return this; }, + onChildrenUpdate: function (state) { + var changed, + dataScope, + elemDataScope; + + if (state && !this.defaultState.length) { + this.defaultState = utils.copy(this.recordData()); + + changed = this.findChangedElems(this.elems()); + dataScope = this.elems()[0].dataScope.split('.'); + dataScope.splice(dataScope.length - 1, 1); + + changed.forEach(function (elem) { + elemDataScope = elem.dataScope.split('.'); + elemDataScope.splice(0, dataScope.length); + + this.setValueByPath(this.defaultState, elemDataScope, elem.initialValue); + }, this); + } + }, + + getDefaultState: function () { + if (!this.defaultState.length) { + this.defaultState = utils.copy(this.recordData()); + } + }, + + setValueByPath: function (obj, path, value) { + var prop; + + if (_.isString(path)) { + path = path.split('.'); + } + + if (path.length - 1) { + prop = obj[path[0]]; + path.splice(0,1); + + this.setValueByPath(prop, path , value); + } else if (path.length) { + obj[path[0]] = value; + } + + }, + + findChangedElems: function (array, changed) { + changed = changed || []; + + array.forEach(function (elem) { + if (_.isFunction(elem.elems)) { + this.findChangedElems(elem.elems(), changed) + } else if (elem.hasChanged()) { + changed.push(elem); + } + }, this); + + return changed; + }, + /** * @inheritdoc */ @@ -254,33 +332,26 @@ define([ * Checks whether component's state is default or not */ checkDefaultState: function () { - var result = true, - recordsData = utils.copy(this.recordData()), - currentData = this.deleteProperty ? - _.filter(recordsData, function (elem) { - return elem[this.deleteProperty] !== this.deleteValue; - }, this) : recordsData; - - if (_.isArray(this.defaultState)) { - result = compareArrays(this.defaultState, currentData); + if (this.name === 'product_form.product_form.related.related.related') { + debugger; } - this.isDefaultState(result); - }, - - /** - * Inits default component state - * - * @param {Array} data - * - * @returns Chainable. - */ - initDefaultState: function (data) { - var defaultState = data || utils.copy(this.recordData()); - - this.defaultState = defaultState; - - return this; + if ( + !this.defaultState.length && + _.isArray(this.recordData()) && + !this.recordData().filter(function (data) { + return !data.initialize; + }).length + ) { + this.defaultState = utils.copy(this.recordData().filter(function (data) { + return data.initialize; + })); + + this.defaultState.forEach(function(data){ + delete data.initialize; + }) + } + this.changed(!compareArrays(this.defaultState, this.recordData())); }, /** @@ -289,14 +360,14 @@ define([ * @param {Boolean} val */ updateTrigger: function (val) { - this.trigger('update', !val); + this.trigger('update', val); }, /** * Returns component state */ hasChanged: function () { - return !this.isDefaultState(); + return this.changed(); }, /** @@ -451,7 +522,7 @@ define([ */ getRecordCount: function () { return _.filter(this.recordData(), function (record) { - return record[this.deleteProperty] !== this.deleteValue; + return record && record[this.deleteProperty] !== this.deleteValue; }, this).length; }, @@ -504,6 +575,8 @@ define([ * @param {Number} page - current page */ changePage: function (page) { + this.getDefaultState() + if (page === 1 && !this.recordData().length) { return false; } -- GitLab From e785ce659d7d7f60e559a26f250ba5489339e46d Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Tue, 21 Jun 2016 16:29:01 +0300 Subject: [PATCH 052/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/js/dynamic-rows/dynamic-rows.js | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index fe5b5cee586..6da291077b9 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -180,9 +180,6 @@ define([ } - if (this.name === 'product_form.product_form.related.related.related') { - debugger; - } this.on('recordData', this.checkDefaultState.bind(this)); return this; @@ -236,7 +233,8 @@ define([ dataScope, elemDataScope; - if (state && !this.defaultState.length) { + if (state && !this.initialState) { + this.initialState = true; this.defaultState = utils.copy(this.recordData()); changed = this.findChangedElems(this.elems()); @@ -253,7 +251,8 @@ define([ }, getDefaultState: function () { - if (!this.defaultState.length) { + if (!this.initialState) { + this.initialState = true; this.defaultState = utils.copy(this.recordData()); } }, @@ -332,17 +331,14 @@ define([ * Checks whether component's state is default or not */ checkDefaultState: function () { - if (this.name === 'product_form.product_form.related.related.related') { - debugger; - } - if ( - !this.defaultState.length && + !this.initialState && _.isArray(this.recordData()) && !this.recordData().filter(function (data) { return !data.initialize; }).length ) { + this.initialState = true; this.defaultState = utils.copy(this.recordData().filter(function (data) { return data.initialize; })); @@ -350,6 +346,13 @@ define([ this.defaultState.forEach(function(data){ delete data.initialize; }) + } else if ( !this.initialState && + _.isArray(this.recordData()) && + this.recordData().filter(function (data) { + return !data.initialize; + }).length + ) { + this.initialState = true; } this.changed(!compareArrays(this.defaultState, this.recordData())); }, @@ -421,6 +424,7 @@ define([ _.extend(data, { label: cell.config.label, name: cell.name, + required: cell.required, columnsHeaderClasses: cell.config.columnsHeaderClasses }); -- GitLab From f60d02bffb534c8ac9f342faae6e6b67b55e0982 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Wed, 22 Jun 2016 16:09:29 +0300 Subject: [PATCH 053/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/js/dynamic-rows/dynamic-rows.js | 40 ++++++++++++++++--- .../dynamic-rows/templates/collapsible.html | 2 +- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 6da291077b9..2279503e57d 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -216,9 +216,7 @@ define([ this._super(); elem.on({ 'deleteRecord': function(index, id){ - this.getDefaultState(); - this.processingDeleteRecord(index, id); - this.changed(!compareArrays(this.defaultState, this.recordData())); + this.deleteHandler(index, id); }.bind(this), 'update': function (state) { this.onChildrenUpdate(state); @@ -228,6 +226,16 @@ define([ return this; }, + deleteHandler: function (index, id) { + this.getDefaultState(); + this.processingDeleteRecord(index, id); + this.changed(!compareArrays(this.defaultState, this.arrFilter(this.relatedData))); + }, + + compare: function(ar1, ar2) { + return compareArrays(ar1, ar2) + }, + onChildrenUpdate: function (state) { var changed, dataScope, @@ -253,7 +261,7 @@ define([ getDefaultState: function () { if (!this.initialState) { this.initialState = true; - this.defaultState = utils.copy(this.recordData()); + this.defaultState = utils.copy(this.arrFilter(this.recordData())); } }, @@ -354,7 +362,29 @@ define([ ) { this.initialState = true; } - this.changed(!compareArrays(this.defaultState, this.recordData())); + this.changed(!compareArrays(this.defaultState, this.arrFilter(this.relatedData))); + }, + + arrFilter: function (data) { + var prop; + + data.forEach(function (elem) { + for (prop in elem) { + if (_.isArray(elem[prop])) { + elem[prop] = _.filter(elem[prop], function (elemProp) { + return elemProp[this.deleteProperty] !== this.deleteValue; + }, this); + + elem[prop].forEach(function (elemProp) { + if (_.isArray(elemProp)) { + elem[prop] = this.arrFilter(elemProp); + } + }, this) + } + } + }, this); + + return data; }, /** diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html index bfe935086e5..c5ae9491885 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/collapsible.html @@ -46,7 +46,7 @@ type="button" title="'Delete'" click="function(){ - $parents[1].deleteRecord($parent.index, $parent.recordId) + $parents[1].deleteHandler($parent.index, $parent.recordId) }"> <span text="'Delete'"/> </button> -- GitLab From aa2840ce1a099b51c878243fa1462dba641d8e70 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Thu, 23 Jun 2016 12:41:25 +0300 Subject: [PATCH 054/838] MAGETWO-53852: Event update works incorrectly --- .../web/template/dynamic-rows/grid.html | 2 +- .../base/web/js/dynamic-rows/dynamic-rows.js | 217 +++++++++++------- .../dynamic-rows/templates/default.html | 6 +- .../dynamic-rows/templates/grid.html | 2 +- 4 files changed, 135 insertions(+), 92 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html index f3642eedf6f..d1830f5d7e2 100644 --- a/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html +++ b/app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html @@ -51,10 +51,10 @@ <th repeat="foreach: labels, item: '$label'" class="data-grid-th" - text="$label().label" visible="$label().visible" disable="$label().disabled" css="setClasses($label())"> + <span text="$label().label"/> </th> </tr> </thead> diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 2279503e57d..63904800b3f 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -117,7 +117,6 @@ define([ isDifferedFromDefault: false, defaultState: [], changed: false, - isDefaultState: true, fallbackResetTpl: 'ui/form/element/helper/fallback-reset-link', dndConfig: { name: '${ $.name }_dnd', @@ -151,7 +150,7 @@ define([ dnd: '${ $.dndConfig.name }' }, pages: 1, - pageSize: 20, + pageSize: 5, relatedData: [], currentPage: 1, startIndex: 0 @@ -165,22 +164,46 @@ define([ * @returns {Object} Chainable. */ initialize: function () { - _.bindAll(this, 'processingDeleteRecord', 'onChildrenUpdate'); + _.bindAll(this, + 'processingDeleteRecord', + 'onChildrenUpdate', + 'checkDefaultState', + 'renderColumnsHeader' + ); + this._super() .initChildren() .initDnd() - .setColumnsHeaderListener() .initDefaultRecord() + .setInitialProperty() + .setColumnsHeaderListener() .checkSpinner(); - if (_.isArray(this.recordData())) { - this.recordData.each(function (data, index) { - this.source.set(this.dataScope + '.' + this.index + '.' + index + '.initialize', true); - }, this); + this.on('recordData', this.checkDefaultState); - } + return this; + }, + + /** + * @inheritdoc + */ + bubble: function (event) { + if (event === 'deleteRecord' || event === 'update') { + return false; + } + + return this._super(); + }, - this.on('recordData', this.checkDefaultState.bind(this)); + /** + * Inits DND module + * + * @returns {Object} Chainable. + */ + initDnd: function () { + if (this.dndConfig.enabled) { + layout([this.dndConfig]); + } return this; }, @@ -215,7 +238,7 @@ define([ initElement: function (elem) { this._super(); elem.on({ - 'deleteRecord': function(index, id){ + 'deleteRecord': function (index, id) { this.deleteHandler(index, id); }.bind(this), 'update': function (state) { @@ -226,45 +249,77 @@ define([ return this; }, + /** + * Handler for deleteRecord event + * + * @param {Number|String} index - element index + * @param {Number|String} id + */ deleteHandler: function (index, id) { - this.getDefaultState(); + this.setDefaultState(); this.processingDeleteRecord(index, id); - this.changed(!compareArrays(this.defaultState, this.arrFilter(this.relatedData))); + this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); }, - compare: function(ar1, ar2) { - return compareArrays(ar1, ar2) + /** + * Set initial property to records data + * + * @returns {Object} Chainable. + */ + setInitialProperty: function () { + if (_.isArray(this.recordData())) { + this.recordData.each(function (data, index) { + this.source.set(this.dataScope + '.' + this.index + '.' + index + '.initialize', true); + }, this); + } + + return this; }, + /** + * Handler for update event + * + * @param {Boolean} state + */ onChildrenUpdate: function (state) { var changed, dataScope, - elemDataScope; - - if (state && !this.initialState) { - this.initialState = true; - this.defaultState = utils.copy(this.recordData()); + changedElemDataScope; - changed = this.findChangedElems(this.elems()); + if (state && !this.hasInitialState) { + this.setDefaultState(); + changed = this.getChangedElems(this.elems()); dataScope = this.elems()[0].dataScope.split('.'); dataScope.splice(dataScope.length - 1, 1); - changed.forEach(function (elem) { - elemDataScope = elem.dataScope.split('.'); - elemDataScope.splice(0, dataScope.length); - - this.setValueByPath(this.defaultState, elemDataScope, elem.initialValue); + changedElemDataScope = elem.dataScope.split('.'); + changedElemDataScope.splice(0, dataScope.length); + this.setValueByPath(this.defaultState, changedElemDataScope, elem.initialValue); }, this); } + + this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); }, - getDefaultState: function () { - if (!this.initialState) { - this.initialState = true; - this.defaultState = utils.copy(this.arrFilter(this.recordData())); + /** + * Set default dynamic-rows state + * + * @param {Array} data - defaultState data + */ + setDefaultState: function (data) { + if (!this.hasInitialState) { + this.hasInitialState = true; + this.defaultState = data ? data : utils.copy(this.arrayFilter(this.recordData())); } }, + /** + * Sets value to object by string path + * + * @param {Object} obj + * @param {Array|String} path + * @param {*} value + */ setValueByPath: function (obj, path, value) { var prop; @@ -274,21 +329,26 @@ define([ if (path.length - 1) { prop = obj[path[0]]; - path.splice(0,1); - - this.setValueByPath(prop, path , value); + path.splice(0, 1); + this.setValueByPath(prop, path, value); } else if (path.length) { obj[path[0]] = value; } - }, - findChangedElems: function (array, changed) { + /** + * Returns elements which changed self state + * + * @param {Array} array - data array + * @param {Array} changed - array with changed elements + * @returns {Array} changed - array with changed elements + */ + getChangedElems: function (array, changed) { changed = changed || []; array.forEach(function (elem) { if (_.isFunction(elem.elems)) { - this.findChangedElems(elem.elems(), changed) + this.getChangedElems(elem.elems(), changed); } else if (elem.hasChanged()) { changed.push(elem); } @@ -297,30 +357,6 @@ define([ return changed; }, - /** - * @inheritdoc - */ - bubble: function (event) { - if (event === 'deleteRecord') { - return false; - } - - return this._super(); - }, - - /** - * Inits DND module - * - * @returns {Object} Chainable. - */ - initDnd: function () { - if (this.dndConfig.enabled) { - layout([this.dndConfig]); - } - - return this; - }, - /** * Checks columnsHeaderAfterRender property, * and set listener on elems if needed @@ -329,7 +365,11 @@ define([ */ setColumnsHeaderListener: function () { if (this.columnsHeaderAfterRender) { - this.on('recordData', this.renderColumnsHeader.bind(this)); + this.on('recordData', this.renderColumnsHeader); + + if (_.isArray(this.recordData()) && this.recordData().length) { + this.renderColumnsHeader(); + } } return this; @@ -339,35 +379,37 @@ define([ * Checks whether component's state is default or not */ checkDefaultState: function () { - if ( - !this.initialState && - _.isArray(this.recordData()) && - !this.recordData().filter(function (data) { + var isRecordDataArray = _.isArray(this.recordData()), + initialize, + hasNotDefaultRecords = isRecordDataArray ? !!this.recordData().filter(function (data) { return !data.initialize; - }).length - ) { - this.initialState = true; - this.defaultState = utils.copy(this.recordData().filter(function (data) { - return data.initialize; - })); + }).length : false; - this.defaultState.forEach(function(data){ + if (!this.hasInitialState && isRecordDataArray && !hasNotDefaultRecords) { + this.hasInitialState = true; + this.defaultState = utils.copy(this.recordData().filter(function (data) { + initialize = data.initialize; delete data.initialize; - }) - } else if ( !this.initialState && - _.isArray(this.recordData()) && - this.recordData().filter(function (data) { - return !data.initialize; - }).length - ) { - this.initialState = true; + + return initialize; + })); + } else if (!this.hasInitialState && isRecordDataArray && hasNotDefaultRecords) { + this.hasInitialState = true; } - this.changed(!compareArrays(this.defaultState, this.arrFilter(this.relatedData))); + + this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); }, - arrFilter: function (data) { + /** + * Filters out deleted items from array + * + * @param {Array} data + * @returns {Array} filtered array + */ + arrayFilter: function (data) { var prop; + /*eslint-disable no-loop-func*/ data.forEach(function (elem) { for (prop in elem) { if (_.isArray(elem[prop])) { @@ -377,13 +419,15 @@ define([ elem[prop].forEach(function (elemProp) { if (_.isArray(elemProp)) { - elem[prop] = this.arrFilter(elemProp); + elem[prop] = this.arrayFilter(elemProp); } - }, this) + }, this); } } }, this); + /*eslint-enable no-loop-func*/ + return data; }, @@ -449,12 +493,11 @@ define([ if (!this.labels().length) { _.each(this.childTemplate.children, function (cell) { data = this.createHeaderTemplate(cell.config); - cell.config.labelVisible = false; _.extend(data, { label: cell.config.label, name: cell.name, - required: cell.required, + required: !!cell.config.validation, columnsHeaderClasses: cell.config.columnsHeaderClasses }); @@ -609,7 +652,7 @@ define([ * @param {Number} page - current page */ changePage: function (page) { - this.getDefaultState() + this.setDefaultState(); if (page === 1 && !this.recordData().length) { return false; diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index 52e8988e66d..d25a107e821 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -24,11 +24,11 @@ <tr> <th if="dndConfig.enabled"/> <th repeat="foreach: labels, item: '$label'" - text="$label().label" + attr="{'data-name': name}" css="setClasses($label())" visible="$label().visible" - disable="$label().disabled" - attr="{'data-name': name}"/> + disable="$label().disabled"> + <span text="$label().label"/> </th> </tr> </thead> diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html index 450a49ba040..5b09d5fca40 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/grid.html @@ -40,10 +40,10 @@ <th repeat="foreach: labels, item: '$label'" class="data-grid-th" - text="$label().label" visible="$label().visible" disable="$label().disabled" css="$label().columnsHeaderClasses"> + <span text="$label().label"/> </th> </tr> </thead> -- GitLab From 8509cef36df413c11aa783a1e7d5f04e3f04ab12 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Thu, 23 Jun 2016 18:28:39 +0300 Subject: [PATCH 055/838] MAGETWO-53852: Event update works incorrectly --- .../dynamic-rows-import-custom-options.js | 6 ++++++ .../js/components/custom-options-price-type.js | 17 +---------------- .../base/web/js/dynamic-rows/dynamic-rows.js | 5 +++-- .../dynamic-rows/templates/default.html | 4 ++-- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js index 7c5fd3bcb97..10e498ff474 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/dynamic-rows-import-custom-options.js @@ -91,7 +91,13 @@ define([ processingAddChild: function (ctx, index, prop) { if (ctx && !_.isNumber(ctx['option_id'])) { ctx['option_id'] = ++maxId; + } else if (!ctx) { + this.showSpinner(true); + this.addChild(ctx, index, prop); + + return; } + this._super(ctx, index, prop); }, diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js index 49fb47b0a60..107fa05af1d 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/components/custom-options-price-type.js @@ -15,10 +15,7 @@ define([ isFiltered: null, defaultOptions: null, filteredOptions: null, - bannedOptions: [], - listens: { - 'visible': 'updateValue' - } + bannedOptions: [] }, /** @@ -74,18 +71,6 @@ define([ } return this.filteredOptions; - }, - - /** - * Clears value of hidden select - * @param {Boolean} visible - */ - updateValue: function (visible) { - if (visible) { - this.updateOptions(); - } else { - this.value(null); - } } }); }); diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 63904800b3f..9635f9046bc 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -385,7 +385,7 @@ define([ return !data.initialize; }).length : false; - if (!this.hasInitialState && isRecordDataArray && !hasNotDefaultRecords) { + if (!this.hasInitialState && isRecordDataArray && hasNotDefaultRecords) { this.hasInitialState = true; this.defaultState = utils.copy(this.recordData().filter(function (data) { initialize = data.initialize; @@ -393,11 +393,12 @@ define([ return initialize; })); + + this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); } else if (!this.hasInitialState && isRecordDataArray && hasNotDefaultRecords) { this.hasInitialState = true; } - this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); }, /** diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index d25a107e821..6492e5cee9d 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -52,7 +52,7 @@ <tfoot> <tr> <td attr="{'colspan': element.getColumnsCount()}" - visible="element.addButton"> + visible="element.addButton || pages() > 1"> <button if="element.addButton" attr="{disabled: disabled, 'data-action': 'add_new_row'}" type="button" @@ -60,7 +60,7 @@ <span text="addButtonLabel"/> </button> - <div class="admin__control-table-pagination" visible="!!element.getRecordCount() && (pages() > 1)"> + <div class="admin__control-table-pagination" visible="!!element.getRecordCount() && pages() > 1"> <div class="admin__data-grid-pager"> <button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button> <input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage"> -- GitLab From e4154987c7dd070ebaf8adbb6748bbf4cd6e537d Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Fri, 24 Jun 2016 12:01:08 +0300 Subject: [PATCH 056/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/js/dynamic-rows/dynamic-rows.js | 5 +---- .../view/base/web/js/dynamic-rows/record.js | 22 +++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 9635f9046bc..d07711b28a7 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -349,7 +349,7 @@ define([ array.forEach(function (elem) { if (_.isFunction(elem.elems)) { this.getChangedElems(elem.elems(), changed); - } else if (elem.hasChanged()) { + } else if (elem.hasOwnProperty('hasChanged') && elem.hasChanged()) { changed.push(elem); } }, this); @@ -395,10 +395,7 @@ define([ })); this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); - } else if (!this.hasInitialState && isRecordDataArray && hasNotDefaultRecords) { - this.hasInitialState = true; } - }, /** diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js index 305de77d47d..cdb74f39c70 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js @@ -5,8 +5,9 @@ define([ 'underscore', - 'uiCollection' -], function (_, uiCollection) { + 'uiCollection', + 'uiRegistry' +], function (_, uiCollection, registry) { 'use strict'; return uiCollection.extend({ @@ -34,6 +35,23 @@ define([ } }, + initialize: function () { + this._super(); + + registry.async(this.name + '.' + this.positionProvider)(function(component){ + component.hasChanged = function () { + return this.value().toString() != this.initialValue.toString(); + }; + + if (!component.initialValue) { + component.initialValue = self.parentComponent().maxPosition; + component.bubble('update', component.hasChanged()); + } + }); + + return this; + }, + /** * Init config * -- GitLab From 66e095566dce1971dc0bcb2bbbed6d39d84554a2 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Fri, 24 Jun 2016 13:14:16 +0300 Subject: [PATCH 057/838] MAGETWO-53852: Event update works incorrectly --- app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js index cdb74f39c70..5c9a51e4342 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js @@ -36,6 +36,8 @@ define([ }, initialize: function () { + var self = this; + this._super(); registry.async(this.name + '.' + this.positionProvider)(function(component){ -- GitLab From f51b382f7017c85b7e317516f4ad2f2ce6cc69b2 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Fri, 24 Jun 2016 16:06:03 +0300 Subject: [PATCH 058/838] MAGETWO-53852: Event update works incorrectly --- .../Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index d07711b28a7..dce3c6d1517 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -394,6 +394,8 @@ define([ return initialize; })); + this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); + } else if (this.hasInitialState) { this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); } }, -- GitLab From deaee8b1d0af68af17a5dcf15182dbc85ef59fb7 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Fri, 24 Jun 2016 16:57:45 +0300 Subject: [PATCH 059/838] MAGETWO-53852: Event update works incorrectly --- .../Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index dce3c6d1517..0c520c2e624 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -349,7 +349,7 @@ define([ array.forEach(function (elem) { if (_.isFunction(elem.elems)) { this.getChangedElems(elem.elems(), changed); - } else if (elem.hasOwnProperty('hasChanged') && elem.hasChanged()) { + } else if (_.isFunction(elem.hasChanged) && elem.hasChanged()) { changed.push(elem); } }, this); -- GitLab From f9197e909f578dde486252732db3b40a48e4120a Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Mon, 27 Jun 2016 11:52:37 +0300 Subject: [PATCH 060/838] MAGETWO-53852: Event update works incorrectly --- .../view/base/web/js/dynamic-rows/dynamic-rows.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 0c520c2e624..cc712cb6a74 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -141,7 +141,7 @@ define([ disabled: 'setDisabled', childTemplate: 'initHeader', recordTemplate: 'onUpdateRecordTemplate', - recordData: 'setDifferedFromDefault parsePagesData', + recordData: 'setDifferedFromDefault parsePagesData setRecordDataToCache', currentPage: 'changePage', elems: 'checkSpinner', changed: 'updateTrigger' @@ -153,9 +153,15 @@ define([ pageSize: 5, relatedData: [], currentPage: 1, + recordDataCache: [], startIndex: 0 }, + setRecordDataToCache: function (data) { + this.recordDataCache = this.recordDataCache && data.length > this.recordDataCache.length ? + data : this.recordDataCache; + }, + /** * Extends instance with default config, calls initialize of parent * class, calls initChildren method, set observe variable. @@ -307,9 +313,11 @@ define([ * @param {Array} data - defaultState data */ setDefaultState: function (data) { + var componentData = this.recordData().length ? this.recordData() : this.recordDataCache; + if (!this.hasInitialState) { this.hasInitialState = true; - this.defaultState = data ? data : utils.copy(this.arrayFilter(this.recordData())); + this.defaultState = data ? data : utils.copy(this.arrayFilter(componentData)); } }, @@ -574,7 +582,7 @@ define([ this.relatedData = this.deleteProperty ? _.filter(data, function (elem) { - return elem[this.deleteProperty] !== this.deleteValue; + return elem && elem[this.deleteProperty] !== this.deleteValue; }, this) : data; pages = Math.ceil(this.relatedData.length / this.pageSize) || 1; -- GitLab From 9e9e16acda67e31eed9db09a17105f3f40736d27 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Wed, 29 Jun 2016 15:31:57 +0300 Subject: [PATCH 061/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/js/dynamic-rows/dynamic-rows.js | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index cc712cb6a74..e8c3b143c09 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -116,6 +116,9 @@ define([ showSpinner: true, isDifferedFromDefault: false, defaultState: [], + defaultPagesState: {}, + pagesChanged: {}, + hasInitialPagesState: {}, changed: false, fallbackResetTpl: 'ui/form/element/helper/fallback-reset-link', dndConfig: { @@ -158,7 +161,7 @@ define([ }, setRecordDataToCache: function (data) { - this.recordDataCache = this.recordDataCache && data.length > this.recordDataCache.length ? + this.recordDataCache = this.recordDataCache && data.length > this.recordDataCache.length ? data : this.recordDataCache; }, @@ -264,7 +267,8 @@ define([ deleteHandler: function (index, id) { this.setDefaultState(); this.processingDeleteRecord(index, id); - this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); + this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.changed(_.some(this.pagesChanged)); }, /** @@ -292,7 +296,7 @@ define([ dataScope, changedElemDataScope; - if (state && !this.hasInitialState) { + if (state && !this.hasInitialPagesState[this.currentPage()]) { this.setDefaultState(); changed = this.getChangedElems(this.elems()); dataScope = this.elems()[0].dataScope.split('.'); @@ -300,11 +304,17 @@ define([ changed.forEach(function (elem) { changedElemDataScope = elem.dataScope.split('.'); changedElemDataScope.splice(0, dataScope.length); - this.setValueByPath(this.defaultState, changedElemDataScope, elem.initialValue); + changedElemDataScope[0] = (parseInt(changedElemDataScope[0], 10) - this.pageSize * (this.currentPage() - 1)).toString(); + this.setValueByPath(this.defaultPagesState[this.currentPage()], changedElemDataScope, elem.initialValue); }, this); } - this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); + this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.changed(_.some(this.pagesChanged)); + }, + + compare: function (a1,a2) { + return compareArrays(a1,a2) }, /** @@ -313,11 +323,11 @@ define([ * @param {Array} data - defaultState data */ setDefaultState: function (data) { - var componentData = this.recordData().length ? this.recordData() : this.recordDataCache; + var componentData = this.getChildItems().length ? this.getChildItems() : this.recordDataCache; - if (!this.hasInitialState) { - this.hasInitialState = true; - this.defaultState = data ? data : utils.copy(this.arrayFilter(componentData)); + if (!this.hasInitialPagesState[this.currentPage()]) { + this.hasInitialPagesState[this.currentPage()] = true; + this.defaultPagesState[this.currentPage()] = data ? data : utils.copy(this.arrayFilter(componentData)); } }, @@ -393,18 +403,19 @@ define([ return !data.initialize; }).length : false; - if (!this.hasInitialState && isRecordDataArray && hasNotDefaultRecords) { - this.hasInitialState = true; - this.defaultState = utils.copy(this.recordData().filter(function (data) { + if (!this.hasInitialPagesState[this.currentPage()] && isRecordDataArray && hasNotDefaultRecords) { + this.hasInitialPagesState[this.currentPage()] = true; + this.defaultPagesState[this.currentPage()] = utils.copy(this.getChildItems().filter(function (data) { initialize = data.initialize; delete data.initialize; return initialize; })); - this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); - } else if (this.hasInitialState) { - this.changed(!compareArrays(this.defaultState, this.arrayFilter(this.relatedData))); + this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.changed(_.some(this.pagesChanged)); + } else if (this.hasInitialPagesState[this.currentPage()]) { + this.changed(_.some(this.pagesChanged)); } }, @@ -660,8 +671,6 @@ define([ * @param {Number} page - current page */ changePage: function (page) { - this.setDefaultState(); - if (page === 1 && !this.recordData().length) { return false; } -- GitLab From 56804b23dfddeff244e162b71e08fffdd4b0d927 Mon Sep 17 00:00:00 2001 From: "Partica, Cristian" <cpartica@magento.com> Date: Fri, 1 Jul 2016 15:33:19 -0500 Subject: [PATCH 062/838] MAGETWO-54785: [GitHub] State/Province field doesn't show as required on the add new address page. #5279 - fixing logic for mandatory labels and error cleanup when switching countries and updating region --- .../Checkout/view/frontend/web/js/region-updater.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index c51fa8fa16b..92c8b08bee6 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -122,8 +122,13 @@ define([ this.options.form = $(this.options.form); - this.options.form && this.options.form.data('validation') && this.options.form.validation('clearError', + this.options.form && this.options.form.data('validator') && this.options.form.validation('clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId); + + // Clean up errors on region & zip fix + $(this.options.regionInputId).removeClass('mage-error').parent().find('[generated]').remove(); + $(this.options.regionListId).removeClass('mage-error').parent().find('[generated]').remove(); + $(this.options.postcodeId).removeClass('mage-error').parent().find('[generated]').remove(); } }, /** @@ -182,11 +187,12 @@ define([ if (!this.options.optionalRegionAllowed) { regionInput.attr('disabled', 'disabled'); } + requiredLabel.removeClass('required'); + regionInput.removeClass('required-entry') } regionList.removeClass('required-entry').hide(); regionInput.show(); - requiredLabel.removeClass('required'); label.attr('for', regionInput.attr('id')); } -- GitLab From 952534ca6db69072fd9db8aab1940727e26bfcca Mon Sep 17 00:00:00 2001 From: "Partica, Cristian" <cpartica@magento.com> Date: Fri, 1 Jul 2016 16:38:45 -0500 Subject: [PATCH 063/838] MAGETWO-54779: [GitHub] Image size for Product Watermarks can't be set #5270 - adding custom validation for AAAxBBB type of inputs in validation rules with translation --- app/code/Magento/Catalog/i18n/en_US.csv | 1 + .../ui_component/design_config_form.xml | 9 ++- .../web/component/image-size-field.js | 57 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index 0745c98d716..6b8a2bc607d 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -700,6 +700,7 @@ Image,Image "Allowed file types: jpeg, gif, png.","Allowed file types: jpeg, gif, png." "Image Opacity","Image Opacity" "Example format: 200x300.","Example format: 200x300." +"The value is not within the specified format eg: 200x300","The value is not within the specified format eg: 200x300" "Image Position","Image Position" Small,Small "Attribute Label","Attribute Label" diff --git a/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml index dc8ced173bc..9852ad74121 100644 --- a/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Catalog/view/adminhtml/ui_component/design_config_form.xml @@ -55,12 +55,13 @@ <field name="watermark_image_size"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Catalog/component/image-size-field</item> <item name="label" xsi:type="string" translate="true">Image Size</item> <item name="dataType" xsi:type="string">text</item> <item name="formElement" xsi:type="string">input</item> <item name="dataScope" xsi:type="string">watermark_image_size</item> <item name="validation" xsi:type="array"> - <item name="validate-digits" xsi:type="boolean">true</item> + <item name="validate-image-size-range" xsi:type="boolean">true</item> </item> <item name="notice" xsi:type="string" translate="true">Example format: 200x300.</item> </item> @@ -118,12 +119,13 @@ <field name="watermark_thumbnail_size"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Catalog/component/image-size-field</item> <item name="label" xsi:type="string" translate="true">Image Size</item> <item name="dataType" xsi:type="string">text</item> <item name="formElement" xsi:type="string">input</item> <item name="dataScope" xsi:type="string">watermark_thumbnail_size</item> <item name="validation" xsi:type="array"> - <item name="validate-digits" xsi:type="boolean">true</item> + <item name="validate-image-size-range" xsi:type="boolean">true</item> </item> <item name="notice" xsi:type="string" translate="true">Example format: 200x300.</item> </item> @@ -181,12 +183,13 @@ <field name="watermark_small_image_size"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Catalog/component/image-size-field</item> <item name="label" xsi:type="string" translate="true">Image Size</item> <item name="dataType" xsi:type="string">text</item> <item name="formElement" xsi:type="string">input</item> <item name="dataScope" xsi:type="string">watermark_small_image_size</item> <item name="validation" xsi:type="array"> - <item name="validate-digits" xsi:type="boolean">true</item> + <item name="validate-image-size-range" xsi:type="boolean">true</item> </item> <item name="notice" xsi:type="string" translate="true">Example format: 200x300.</item> </item> diff --git a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js new file mode 100644 index 00000000000..9f4c05214ac --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js @@ -0,0 +1,57 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'underscore', + 'Magento_Ui/js/lib/validation/utils', + 'Magento_Ui/js/form/element/abstract', + 'Magento_Ui/js/lib/validation/validator' +], function ($, _, utils, Abstract, validator) { + 'use strict'; + + validator.addRule( + 'validate-image-size-range', + function (value) { + var numValue, + dataAttrRange = /^(\d+)x(\d+)?$/, + result = false, + m; + + if (utils.isEmptyNoTrim(value)) { + return true; + } + numValue = utils.parseNumber(value); + + if (isNaN(numValue)) { + return false; + } + + m = dataAttrRange.exec(value); + + if (m) { + if (m.length === 3) { + result = m[1] && m[2]; + } + } + + return result; + }, + $.mage.__('The value is not within the specified format eg: 200x300') + ); + + return Abstract.extend({ + + /** + * Checks for relevant value + * + * @param {*} value + * @returns {Boolean} + */ + isRangeCorrect: function (value) { + return validator('validate-image-size-range', value); + } + }); +}); -- GitLab From f37bf56048311ec3c96be1afeb3a58121009a2d0 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@ebay.com> Date: Mon, 4 Jul 2016 12:51:29 +0300 Subject: [PATCH 064/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/js/dynamic-rows/dynamic-rows.js | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index e8c3b143c09..4534f78ba31 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -252,6 +252,9 @@ define([ }.bind(this), 'update': function (state) { this.onChildrenUpdate(state); + }.bind(this), + 'addChild': function () { + this.setDefaultState(); }.bind(this) }); @@ -323,11 +326,22 @@ define([ * @param {Array} data - defaultState data */ setDefaultState: function (data) { - var componentData = this.getChildItems().length ? this.getChildItems() : this.recordDataCache; + var componentData, + childItems; if (!this.hasInitialPagesState[this.currentPage()]) { + childItems = this.getChildItems(); + componentData = childItems.length ? + utils.copy(childItems) : + utils.copy(this.getChildItems(this.recordDataCache)); + componentData.forEach(function (dataObj) { + if (dataObj.hasOwnProperty('initialize')) { + delete dataObj.initialize; + } + }); + this.hasInitialPagesState[this.currentPage()] = true; - this.defaultPagesState[this.currentPage()] = data ? data : utils.copy(this.arrayFilter(componentData)); + this.defaultPagesState[this.currentPage()] = data ? data : this.arrayFilter(componentData); } }, @@ -349,7 +363,7 @@ define([ prop = obj[path[0]]; path.splice(0, 1); this.setValueByPath(prop, path, value); - } else if (path.length) { + } else if (path.length && obj) { obj[path[0]] = value; } }, @@ -415,6 +429,7 @@ define([ this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); this.changed(_.some(this.pagesChanged)); } else if (this.hasInitialPagesState[this.currentPage()]) { + this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); this.changed(_.some(this.pagesChanged)); } }, @@ -605,10 +620,15 @@ define([ * * @returns {Array} data */ - getChildItems: function () { + getChildItems: function (data, page) { + var dataRecord = data || this.relatedData, + startIndex; + this.startIndex = (~~this.currentPage() - 1) * this.pageSize; - return this.relatedData.slice(this.startIndex, this.startIndex + this.pageSize); + startIndex = page || this.startIndex; + + return dataRecord.slice(startIndex, this.startIndex + this.pageSize); }, /** @@ -639,6 +659,10 @@ define([ * @param {Number|String} prop - additional property to element */ processingAddChild: function (ctx, index, prop) { + console.log('3', this.name); + + this.bubble('addChild', false); + if (this.relatedData.length && this.relatedData.length % this.pageSize === 0) { this.clear(); this.pages(this.pages() + 1); -- GitLab From 09feea1742aa6ed934c1146e203619790c57b876 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 4 Jul 2016 13:46:01 +0300 Subject: [PATCH 065/838] MAGETWO-54722: Example password enocurages password reuse --- setup/view/magento/setup/create-admin-account.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/view/magento/setup/create-admin-account.phtml b/setup/view/magento/setup/create-admin-account.phtml index 35c0c911b18..135fb89b977 100644 --- a/setup/view/magento/setup/create-admin-account.phtml +++ b/setup/view/magento/setup/create-admin-account.phtml @@ -19,7 +19,7 @@ $passwordWizard = sprintf( </div> <p>%s</p>', 'Password Strength:', - 'Enter a mix of 7 or more numbers and letters. For a stronger password, include at least one small letter, big letter, and symbol (Ex: BuyIt$54).' + 'Enter a mix of 7 or more numbers and letters. For a stronger password, include at least one small letter, big letter, and symbol.' ); ?> -- GitLab From fd938b219af8511969240b4003575605e8a37297 Mon Sep 17 00:00:00 2001 From: Anton Evers <anton@eve.rs> Date: Wed, 6 Jul 2016 13:14:10 +0200 Subject: [PATCH 066/838] Fixes #5495 method `select` is overwritten to shift `this.active` from the `.all-categories` link to the clicked menu node. After opening a menu item `this.active` is filled with the `.all-categories` link and the `select` method does not expect that. It closes all menu items and skips the activation of the selected menu item. A `collapseAll` event is triggered for mobile devices if an open menu item is clicked so it closes it again. method `expand` is overwritten to skip expansion of the clicked menu node of the menu node was already open. This event would otherwise take place directly after the added `collapseAll`. Although this is a working solution it does rewrite two major methods of the jQuery UI menu which I feel should not be necessary. So if someone would like to look into a different solution, be welcome. --- lib/web/mage/menu.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index a3f4ad36d0a..6d2b2019bbb 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -272,6 +272,9 @@ define([ if (!target.hasClass('level-top') || !target.has(".ui-menu").length) { window.location.href = target.find('> a').attr('href'); } + }, + "click .ui-menu-item:has(.ui-state-active)": function (event) { + this.collapseAll(event, true); } }); @@ -386,6 +389,40 @@ define([ }; return setTimeout(handlerProxy, delay || 0); + }, + , + expand: function( event ) { + var newItem = this.active && + this.active + .children( ".ui-menu " ) + .children( ".ui-menu-item" ) + .first(); + + if ( newItem && newItem.length ) { + if (newItem.closest( ".ui-menu" ).is( ":visible" ) + && newItem.closest( ".ui-menu" ).has( ".all-categories" ) + ) { + return; + } + + this._open( newItem.parent() ); + + // Delay so Firefox will not hide activedescendant change in expanding submenu from AT + this._delay(function() { + this.focus( event, newItem ); + }); + } + }, + select: function( event ) { + this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); + if (this.active.is( ".all-category" )) { + this.active = $( event.target ).closest( ".ui-menu-item" ); + } + var ui = { item: this.active }; + if ( !this.active.has( ".ui-menu" ).length ) { + this.collapseAll( event, true ); + } + this._trigger( "select", event, ui ); } }); -- GitLab From f69a1fca5e45a2ac243a4b124e185d9e0cb80017 Mon Sep 17 00:00:00 2001 From: Anton Evers <anton@eve.rs> Date: Wed, 6 Jul 2016 14:25:12 +0200 Subject: [PATCH 067/838] remove extra comma --- lib/web/mage/menu.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/web/mage/menu.js b/lib/web/mage/menu.js index 6d2b2019bbb..57437e7dcd9 100644 --- a/lib/web/mage/menu.js +++ b/lib/web/mage/menu.js @@ -390,7 +390,6 @@ define([ return setTimeout(handlerProxy, delay || 0); }, - , expand: function( event ) { var newItem = this.active && this.active -- GitLab From 3109c8e96bcd08041f558be65a2a4e3d213d22a4 Mon Sep 17 00:00:00 2001 From: dvinograd <dmytro@vaimo.com> Date: Thu, 21 Jul 2016 12:03:56 +0200 Subject: [PATCH 068/838] Fix translations issues in lib/web/mage/validation.js lib/web/mage/validation/validation.js lib/web/mage/backend/validation.js --- lib/web/mage/backend/validation.js | 6 +- lib/web/mage/validation.js | 192 +++++++++++++++----------- lib/web/mage/validation/validation.js | 10 +- 3 files changed, 116 insertions(+), 92 deletions(-) diff --git a/lib/web/mage/backend/validation.js b/lib/web/mage/backend/validation.js index 3d999e3c47b..026b41ae202 100644 --- a/lib/web/mage/backend/validation.js +++ b/lib/web/mage/backend/validation.js @@ -224,7 +224,7 @@ } return true; }, - 'Please enter a number greater 0 in this field.' + $.mage.__('Please enter a number greater 0 in this field.') ], 'validate-rating': [ function () { @@ -236,7 +236,7 @@ }); return noError; }, - 'Please select one of each ratings above.' + $.mage.__('Please select one of each ratings above.') ], 'validate-downloadable-file': [ function (v, element) { @@ -267,7 +267,7 @@ } return true; }, - 'Please specify Url.' + $.mage.__('Please specify Url.') ] }, function (rule, i) { rule.unshift(i); diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index aff3141c2d4..7ea89e78843 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -167,13 +167,13 @@ function (value, element, params) { return this.optional(element) || $.mage.stripHtml(value).match(/\b\w+\b/g).length < params; }, - 'Please enter {0} words or less.' + $.mage.__('Please enter {0} words or less.') ], "min-words": [ function (value, element, params) { return this.optional(element) || $.mage.stripHtml(value).match(/\b\w+\b/g).length >= params; }, - 'Please enter at least {0} words.' + $.mage.__('Please enter at least {0} words.') ], "range-words": [ function (value, element, params) { @@ -181,43 +181,43 @@ $.mage.stripHtml(value).match(/\b\w+\b/g).length >= params[0] && value.match(/bw+b/g).length < params[1]; }, - 'Please enter between {0} and {1} words.' + $.mage.__('Please enter between {0} and {1} words.') ], "letters-with-basic-punc": [ function (value, element) { return this.optional(element) || /^[a-z\-.,()'\"\s]+$/i.test(value); }, - 'Letters or punctuation only please' + $.mage.__('Letters or punctuation only please') ], "alphanumeric": [ function (value, element) { return this.optional(element) || /^\w+$/i.test(value); }, - 'Letters, numbers, spaces or underscores only please' + $.mage.__('Letters, numbers, spaces or underscores only please') ], "letters-only": [ function (value, element) { return this.optional(element) || /^[a-z]+$/i.test(value); }, - 'Letters only please' + $.mage.__('Letters only please') ], "no-whitespace": [ function (value, element) { return this.optional(element) || /^\S+$/i.test(value); }, - 'No white space please' + $.mage.__('No white space please') ], "zip-range": [ function (value, element) { return this.optional(element) || /^90[2-5]-\d{2}-\d{4}$/.test(value); }, - 'Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx' + $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx') ], "integer": [ function (value, element) { return this.optional(element) || /^-?\d+$/.test(value); }, - 'A positive or negative non-decimal number please' + $.mage.__('A positive or negative non-decimal number please') ], "vinUS": [ function (v) { @@ -260,7 +260,7 @@ } return false; }, - 'The specified vehicle identification number (VIN) is invalid.' + $.mage.__('The specified vehicle identification number (VIN) is invalid.') ], "dateITA": [ function (value, element) { @@ -283,7 +283,7 @@ } return this.optional(element) || check; }, - 'Please enter a correct date' + $.mage.__('Please enter a correct date') ], "dateNL": [ function (value, element) { @@ -295,13 +295,13 @@ function (value, element) { return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){0,2}$/.test(value); }, - 'Please enter a valid time, between 00:00 and 23:59' + $.mage.__('Please enter a valid time, between 00:00 and 23:59') ], "time12h": [ function (value, element) { return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))$/i.test(value); }, - 'Please enter a valid time, between 00:00 am and 12:00 pm' + $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm') ], "phoneUS": [ function (phone_number, element) { @@ -309,27 +309,27 @@ return this.optional(element) || phone_number.length > 9 && phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/); }, - 'Please specify a valid phone number' + $.mage.__('Please specify a valid phone number') ], "phoneUK": [ function (phone_number, element) { return this.optional(element) || phone_number.length > 9 && phone_number.match(/^(\(?(0|\+44)[1-9]{1}\d{1,4}?\)?\s?\d{3,4}\s?\d{3,4})$/); }, - 'Please specify a valid phone number' + $.mage.__('Please specify a valid phone number') ], "mobileUK": [ function (phone_number, element) { return this.optional(element) || phone_number.length > 9 && phone_number.match(/^((0|\+44)7(5|6|7|8|9){1}\d{2}\s?\d{6})$/); }, - 'Please specify a valid mobile number' + $.mage.__('Please specify a valid mobile number') ], "stripped-min-length": [ function (value, element, param) { return $(value).text().length >= param; }, - 'Please enter at least {0} characters' + $.mage.__('Please enter at least {0} characters') ], "email2": [ function (value, element) { @@ -408,25 +408,25 @@ } return false; }, - 'Please enter a valid credit card number.' + $.mage.__('Please enter a valid credit card number.') ], "ipv4": [ function (value, element) { return this.optional(element) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value); }, - 'Please enter a valid IP v4 address.' + $.mage.__('Please enter a valid IP v4 address.') ], "ipv6": [ function (value, element) { return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value); }, - 'Please enter a valid IP v6 address.' + $.mage.__('Please enter a valid IP v6 address.') ], "pattern": [ function (value, element, param) { return this.optional(element) || param.test(value); }, - 'Invalid format.' + $.mage.__('Invalid format.') ], "allow-container-className": [ function (element) { @@ -440,67 +440,67 @@ function (value) { return !/<(\/)?\w+/.test(value); }, - 'HTML tags are not allowed.' + $.mage.__('HTML tags are not allowed.') ], "validate-select": [ function (value) { return ((value !== "none") && (value != null) && (value.length !== 0)); }, - 'Please select an option.' + $.mage.__('Please select an option.') ], "validate-no-empty": [ function (value) { return !$.mage.isEmpty(value); }, - 'Empty Value.' + $.mage.__('Empty Value.') ], "validate-alphanum-with-spaces": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9 ]+$/.test(v); }, - 'Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.' + $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.') ], "validate-data": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(v); }, - 'Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.' + $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') ], "validate-street": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[ \w]{3,}([A-Za-z]\.)?([ \w]*\#\d+)?(\r\n| )[ \w]{3,}/.test(v); }, - 'Please use only letters (a-z or A-Z), numbers (0-9), spaces and "#" in this field.' + $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and "#" in this field.') ], "validate-phoneStrict": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v); }, - 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.' + $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.') ], "validate-phoneLax": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^((\d[\-. ]?)?((\(\d{3}\))|\d{3}))?[\-. ]?\d{3}[\-. ]?\d{4}$/.test(v); }, - 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.' + $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.') ], "validate-fax": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v); }, - 'Please enter a valid fax number (Ex: 123-456-7890).' + $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).') ], "validate-email": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(v); }, - 'Please enter a valid email address (Ex: johndoe@domain.com).' + $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).') ], "validate-emailSender": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[\S ]+$/.test(v); }, - 'Please enter a valid email address (Ex: johndoe@domain.com).' + $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).') ], "validate-password": [ function (v) { @@ -514,7 +514,7 @@ } return !(pass.length > 0 && pass.length < 6); }, - 'Please enter 6 or more characters. Leading and trailing spaces will be ignored.' + $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.') ], "validate-admin-password": [ function (v) { @@ -534,7 +534,7 @@ } return true; }, - 'Please enter 7 or more characters, using both numeric and alphabetic.' + $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.') ], "validate-customer-password": [ function (v, elm) { @@ -585,35 +585,35 @@ return (/^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i).test(v); }, - 'Please enter a valid URL. Protocol is required (http://, https:// or ftp://).' + $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).') ], "validate-clean-url": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v) || /^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v); }, - 'Please enter a valid URL. For example http://www.example.com or www.example.com.' + $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.') ], "validate-xml-identifier": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[A-Z][A-Z0-9_\/-]*$/i.test(v); }, - 'Please enter a valid XML-identifier (Ex: something_1, block5, id-4).' + $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).') ], "validate-ssn": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^\d{3}-?\d{2}-?\d{4}$/.test(v); }, - 'Please enter a valid social security number (Ex: 123-45-6789).' + $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).') ], "validate-zip-us": [ function (v) { return $.mage.isEmptyNoTrim(v) || /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(v); }, - 'Please enter a valid zip code (Ex: 90602 or 90602-1234).' + $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).') ], "validate-date-au": [ function (v) { @@ -630,14 +630,14 @@ parseInt(RegExp.$3, 10) === d.getFullYear(); }, - 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.' + $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.') ], "validate-currency-dollar": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v); }, - 'Please enter a valid $ amount. For example $100.00.' + $.mage.__('Please enter a valid $ amount. For example $100.00.') ], "validate-not-negative-number": [ function (v) { @@ -648,7 +648,7 @@ return !isNaN(v) && v >= 0; }, - 'Please enter a number 0 or greater in this field.' + $.mage.__('Please enter a number 0 or greater in this field.') ], // validate-not-negative-number should be replaced in all places with this one and then removed "validate-zero-or-greater": [ @@ -660,7 +660,7 @@ return !isNaN(v) && v >= 0; }, - 'Please enter a number 0 or greater in this field.' + $.mage.__('Please enter a number 0 or greater in this field.') ], "validate-greater-than-zero": [ function (v) { @@ -670,7 +670,7 @@ v = $.mage.parseNumber(v); return !isNaN(v) && v > 0; }, - 'Please enter a number greater than 0 in this field.' + $.mage.__('Please enter a number greater than 0 in this field.') ], "validate-css-length": [ function (v) { @@ -679,20 +679,20 @@ } return true; }, - 'Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).' + $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).') ], /** @description Additional methods */ "validate-number": [ function (v) { return $.mage.isEmptyNoTrim(v) || (!isNaN($.mage.parseNumber(v)) && /^\s*-?\d*(\.\d*)?\s*$/.test(v)); }, - 'Please enter a valid number in this field.' + $.mage.__('Please enter a valid number in this field.') ], "required-number": [ function (v) { return !!v.length; }, - 'Please enter a valid number in this field.' + $.mage.__('Please enter a valid number in this field.') ], "validate-number-range": [ function (v, elm, param) { @@ -732,14 +732,14 @@ return result; }, - 'The value is not within the specified range.', + $.mage.__('The value is not within the specified range.'), true ], "validate-digits": [ function (v) { return $.mage.isEmptyNoTrim(v) || !/[^\d]/.test(v); }, - 'Please enter a valid number in this field.' + $.mage.__('Please enter a valid number in this field.') ], "validate-digits-range": [ function (v, elm, param) { @@ -779,7 +779,7 @@ return result; }, - 'The value is not within the specified range.', + $.mage.__('The value is not within the specified range.'), true ], 'validate-range': [ @@ -820,31 +820,32 @@ } return result; }, - 'The value is not within the specified range.' + $.mage.__('The value is not within the specified range.') ], "validate-alpha": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z]+$/.test(v); }, - 'Please use letters only (a-z or A-Z) in this field.' + $.mage.__('Please use letters only (a-z or A-Z) in this field.') ], "validate-code": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[a-z]+[a-z0-9_]+$/.test(v); }, - 'Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.' + $.mage.__('Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.') ], "validate-alphanum": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9]+$/.test(v); }, - 'Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.' + $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.') ], "validate-date": [ function (v) { var test = new Date(v); return $.mage.isEmptyNoTrim(v) || !isNaN(test); - }, 'Please enter a valid date.' + }, + $.mage.__('Please enter a valid date.') ], "validate-date-range": [ @@ -867,7 +868,7 @@ return !dependentElements.length || $.mage.isEmptyNoTrim(dependentElements[0].value) || normalizedTime(v) <= normalizedTime(dependentElements[0].value); }, - 'Make sure the To Date is later than or the same as the From Date.' + $.mage.__('Make sure the To Date is later than or the same as the From Date.') ], "validate-cpassword": [ function () { @@ -888,13 +889,13 @@ } return (pass.val() === conf.val()); }, - 'Please make sure your passwords match.' + $.mage.__('Please make sure your passwords match.') ], "validate-identifier": [ function (v) { return $.mage.isEmptyNoTrim(v) || /^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/.test(v); }, - 'Please enter a valid URL Key (Ex: "example-page", "example-page.html" or "anotherlevel/example-page").' + $.mage.__('Please enter a valid URL Key (Ex: "example-page", "example-page.html" or "anotherlevel/example-page").') ], "validate-zip-international": [ /*function(v) { @@ -904,7 +905,7 @@ function () { return true; }, - 'Please enter a valid zip code.' + $.mage.__('Please enter a valid zip code.') ], "validate-one-required": [ function (v, elm) { @@ -914,13 +915,13 @@ return $(elm).val(); }).length > 0; }, - 'Please select one of the options above.' + $.mage.__('Please select one of the options above.') ], "validate-state": [ function (v) { return (v !== 0 || v === ''); }, - 'Please select State/Province.' + $.mage.__('Please select State/Province.') ], "required-file": [ function (v, elm) { @@ -933,7 +934,7 @@ } return result; }, - 'Please select a file.' + $.mage.__('Please select a file.') ], "validate-ajax-error": [ function (v, element) { @@ -962,7 +963,7 @@ } return hasWithValue ^ hasWithNoValue; }, - 'The field isn\'t complete.' + $.mage.__('The field isn\'t complete.') ], "validate-required-datetime": [ function (v, elm, param) { @@ -974,7 +975,7 @@ } return true; }, - 'This is a required field.' + $.mage.__('This is a required field.') ], "validate-one-required-by-name": [ function (v, elm, selector) { @@ -1025,7 +1026,8 @@ } } return true; - }, "Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com." + }, + $.mage.__("Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.") ], "validate-cc-type-select": [ @@ -1041,7 +1043,8 @@ return creditCartTypes[value][0].test($(params).val().replace(/\s+/g, '')); } return false; - }, 'Card type does not match credit card number.' + }, + $.mage.__('Card type does not match credit card number.') ], "validate-cc-number": [ /** @@ -1054,7 +1057,8 @@ return validateCreditCard(value); } return false; - }, 'Please enter a valid credit card number.' + }, + $.mage.__('Please enter a valid credit card number.') ], "validate-cc-type": [ /** @@ -1075,7 +1079,8 @@ } } return false; - }, 'Credit card number does not match credit card type.' + }, + $.mage.__('Credit card number does not match credit card type.') ], "validate-cc-exp": [ /** @@ -1096,7 +1101,8 @@ isValid = !year || year > currentYear || (year == currentYear && month >= currentMonth); } return isValid; - }, 'Incorrect credit card expiration date.' + }, + $.mage.__('Incorrect credit card expiration date.') ], "validate-cc-cvn": [ /** @@ -1114,7 +1120,8 @@ } } return false; - }, 'Please enter a valid credit card verification number.' + }, + $.mage.__('Please enter a valid credit card verification number.') ], "validate-cc-ukss": [ /** @@ -1124,7 +1131,8 @@ */ function (value) { return value; - }, 'Please enter issue number or start date for switch/solo card type.' + }, + $.mage.__('Please enter issue number or start date for switch/solo card type.') ], "validate-length": [ @@ -1163,7 +1171,7 @@ else return true; }, - 'Please enter positive number in this field.' + $.mage.__('Please enter positive number in this field.') ], 'validate-per-page-value-list': [ function (v) { @@ -1176,7 +1184,7 @@ } return isValid; }, - 'Please enter a valid value, ex: 10,20,30' + $.mage.__('Please enter a valid value, ex: 10,20,30') ], 'validate-per-page-value': [ function (v, elm) { @@ -1186,7 +1194,7 @@ var values = $('#' + elm.id + '_values').val().split(','); return values.indexOf(v) != -1; }, - 'Please enter a valid value from list' + $.mage.__('Please enter a valid value from list') ], 'validate-new-password': [ function (v) { @@ -1199,7 +1207,7 @@ } return true; }, - 'Please enter 6 or more characters. Leading and trailing spaces will be ignored.' + $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.') ], 'required-if-not-specified': [ function (value, element, params) { @@ -1223,7 +1231,7 @@ return valid; }, - 'This is a required field.' + $.mage.__('This is a required field.') ], 'required-if-all-sku-empty-and-file-not-loaded': [ function (value, element, params) { @@ -1251,7 +1259,8 @@ }); return valid; - }, 'Please enter valid SKU key.' + }, + $.mage.__('Please enter valid SKU key.') ], 'required-if-specified': [ function (value, element, params) { @@ -1276,7 +1285,7 @@ return valid; }, - 'This is a required field.' + $.mage.__('This is a required field.') ], 'required-number-if-specified': [ function (value, element, params) { @@ -1295,7 +1304,7 @@ return valid ? !!value.length : true; }, - 'Please enter a valid number.' + $.mage.__('Please enter a valid number.') ], 'datetime-validation': [ function (value, element) { @@ -1308,19 +1317,19 @@ return isValid; }, - 'This is required field' + $.mage.__('This is required field') ], 'required-text-swatch-entry': [ tableSingleValidation, - 'Admin is a required field in the each row.' + $.mage.__('Admin is a required field in the each row.') ], 'required-visual-swatch-entry': [ tableSingleValidation, - 'Admin is a required field in the each row.' + $.mage.__('Admin is a required field in the each row.') ], 'required-dropdown-attribute-entry': [ tableSingleValidation, - 'Admin is a required field in the each row.' + $.mage.__('Admin is a required field in the each row.') ], 'validate-item-quantity': [ function (value, element, params) { @@ -1354,7 +1363,22 @@ } }); $.validator.messages = $.extend($.validator.messages, { - required: $.mage.__('This is a required field.') + required: $.mage.__('This is a required field.'), + remote: $.mage.__('Please fix this field.'), + email: $.mage.__('Please enter a valid email address.'), + url: $.mage.__('Please enter a valid URL.'), + date: $.mage.__('Please enter a valid date.'), + dateISO: $.mage.__('Please enter a valid date (ISO).'), + number: $.mage.__('Please enter a valid number.'), + digits: $.mage.__('Please enter only digits.'), + creditcard: $.mage.__('Please enter a valid credit card number.'), + equalTo: $.mage.__('Please enter the same value again.'), + maxlength: $.validator.format($.mage.__('Please enter no more than {0} characters.')), + minlength: $.validator.format($.mage.__('Please enter at least {0} characters.')), + rangelength: $.validator.format($.mage.__('Please enter a value between {0} and {1} characters long.')), + range: $.validator.format($.mage.__('Please enter a value between {0} and {1}.')), + max: $.validator.format($.mage.__('Please enter a value less than or equal to {0}.')), + min: $.validator.format($.mage.__('Please enter a value greater than or equal to {0}.')) }); if ($.metadata) { diff --git a/lib/web/mage/validation/validation.js b/lib/web/mage/validation/validation.js index a60ca5e737b..b1c4db994ed 100644 --- a/lib/web/mage/validation/validation.js +++ b/lib/web/mage/validation/validation.js @@ -36,7 +36,7 @@ }); return result && total > 0; }, - 'Please specify the quantity of product(s).' + $.mage.__('Please specify the quantity of product(s).') ], 'validate-one-checkbox-required-by-name': [ function (value, element, params) { @@ -60,7 +60,7 @@ return false; } }, - 'Please select one of the options.' + $.mage.__('Please select one of the options.') ], 'validate-date-between': [ function (value, element, params) { @@ -89,7 +89,7 @@ yearVal = $(dob).find(params[2]).find('input:text').val(), dobLength = dayVal.length + monthVal.length + yearVal.length; if (params[3] && dobLength === 0) { - this.dobErrorMessage = 'This is a required field.'; + this.dobErrorMessage = $.mage.__('This is a required field.'); return false; } if (!params[3] && dobLength === 0) { @@ -100,11 +100,11 @@ year = parseInt(yearVal, 10) || 0, curYear = (new Date()).getFullYear(); if (!day || !month || !year) { - this.dobErrorMessage = 'Please enter a valid full date.'; + this.dobErrorMessage = $.mage.__('Please enter a valid full date.'); return false; } if (month < 1 || month > 12) { - this.dobErrorMessage = 'Please enter a valid month (1-12).'; + this.dobErrorMessage = $.mage.__('Please enter a valid month (1-12).'); return false; } if (year < 1900 || year > curYear) { -- GitLab From 0c06f250dee25056e48b327d60282d1fdb3764d3 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Fri, 22 Jul 2016 19:06:55 +0300 Subject: [PATCH 069/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront --- .../view/frontend/templates/messages.phtml | 8 +++++-- .../view/base/web/js/form/element/abstract.js | 21 ++++++++++++++++++- .../grid/editing/header-buttons.html | 18 +++++++++------- .../web/templates/form/element/checkbox.html | 13 +++++++++++- .../web/templates/form/element/date.html | 3 ++- .../web/templates/form/element/email.html | 3 ++- .../web/templates/form/element/input.html | 6 ++++-- .../web/templates/form/element/password.html | 3 ++- .../web/templates/form/element/select.html | 3 ++- .../frontend/web/templates/form/field.html | 4 ++-- 10 files changed, 62 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Theme/view/frontend/templates/messages.phtml b/app/code/Magento/Theme/view/frontend/templates/messages.phtml index 2bd2357a27e..7ef534ab5d6 100644 --- a/app/code/Magento/Theme/view/frontend/templates/messages.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/messages.phtml @@ -5,7 +5,8 @@ */ ?> <div data-bind="scope: 'messages'"> - <div data-bind="foreach: { data: cookieMessages, as: 'message' }" class="messages"> + <!-- ko if: cookieMessages && cookieMessages.length > 0 --> + <div role="alert" data-bind="foreach: { data: cookieMessages, as: 'message' }" class="messages"> <div data-bind="attr: { class: 'message-' + message.type + ' ' + message.type + ' message', 'data-ui-id': 'message-' + message.type @@ -13,7 +14,9 @@ <div data-bind="html: message.text"></div> </div> </div> - <div data-bind="foreach: { data: messages().messages, as: 'message' }" class="messages"> + <!-- /ko --> + <!-- ko if: messages().messages && messages().messages.length > 0 --> + <div role="alert" data-bind="foreach: { data: messages().messages, as: 'message' }" class="messages"> <div data-bind="attr: { class: 'message-' + message.type + ' ' + message.type + ' message', 'data-ui-id': 'message-' + message.type @@ -21,6 +24,7 @@ <div data-bind="html: message.text"></div> </div> </div> + <!-- /ko --> </div> <script type="text/x-magento-init"> { diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 917b62a5042..7e03a59ab48 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -24,7 +24,7 @@ define([ tooltipTpl: 'ui/form/element/helper/tooltip', fallbackResetTpl: 'ui/form/element/helper/fallback-reset', 'input_type': 'input', - placeholder: '', + placeholder: false, description: '', labelVisible: true, label: '', @@ -114,6 +114,8 @@ define([ _.extend(this, { uid: uid, noticeId: 'notice-' + uid, + errorId: 'error-' + uid, + warningId: 'warning-' + uid, inputName: utils.serializeName(name.join('.')), valueUpdate: valueUpdate }); @@ -436,6 +438,23 @@ define([ */ userChanges: function () { this.valueChangedByUser = true; + }, + + /** + * Returns correct id for 'aria-describedby' accessibility attribute + * + * @returns {String} + */ + setDescriptionId: function () { + var id = false; + + if(this.error().length > 0) { + id = this.errorId; + } else if (this.notice) { + id = this.noticeId; + } + + return id; } }); }); diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html b/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html index ab0131ed667..8ab4a8418c5 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html @@ -4,19 +4,21 @@ * See COPYING.txt for license details. */ --> -<div class="data-grid-info-panel" visible="isMultiEditing || (hasActive() && (hasMessages() || hasErrors() ))"> - <div class="messages" visible="hasMessages() || hasErrors()"> - <div class="message message-warning" visible="hasErrors()"> +<div if="isMultiEditing || (hasActive() && (hasMessages() || hasErrors() ))" + attr="role: (isMultiEditing && multiEditingButtons) ? 'alertdialog' : 'alert'" + class="data-grid-info-panel"> + <div if="hasMessages() || hasErrors()" class="messages"> + <div if="hasErrors()" class="message message-warning"> <strong>There are <text args="countErrors()"/> messages requires your attention.</strong> Please make corrections to the errors in the table below and re-submit. </div> <div class="message" outereach="messages" text="message" - css=" - 'message-warning': type === 'warning', - 'message-error': type === 'error', - 'message-success': type === 'success'"/> + css=" + 'message-warning': type === 'warning', + 'message-error': type === 'error', + 'message-success': type === 'success'"/> </div> - <div class="data-grid-info-panel-actions" visible="isMultiEditing && multiEditingButtons"> + <div if="isMultiEditing && multiEditingButtons" class="data-grid-info-panel-actions"> <button class="action-tertiary" type="button" click="cancel"> <span translate="'Cancel'"/> </button> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html index 50a27e69025..c54cfdbe8e7 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html @@ -5,7 +5,18 @@ */ --> <div class="choice field"> - <input type="checkbox" class="checkbox" data-bind="checked: value, attr: { id: uid, disabled: disabled, name: inputName }, hasFocus: focused"> + <input type="checkbox" + class="checkbox" + data-bind=" + checked: value, + attr: { + id: uid, + disabled: disabled, + name: inputName, + 'aria-describedby': setDescriptionId(), + 'aria-required': required + }, + hasFocus: focused"> <label class="label" data-bind="checked: value, attr: { for: uid }"> <span data-bind="text: description || label"></span> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html index be2034a6a0b..cebeeb636f5 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html @@ -11,6 +11,7 @@ value: value, name: inputName, placeholder: placeholder, - 'aria-describedby': noticeId, + 'aria-describedby': setDescriptionId(), + 'aria-required': required, disabled: disabled }" /> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html index dfd75630e08..9f11ba35bc7 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html @@ -10,7 +10,8 @@ attr: { name: inputName, placeholder: placeholder, - 'aria-describedby': noticeId, + 'aria-describedby': setDescriptionId(), + 'aria-required': required id: uid, disabled: disabled }"/> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html index 01234333d58..0eee7c2cf23 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html @@ -11,7 +11,9 @@ attr: { name: inputName, placeholder: placeholder, - 'aria-describedby': noticeId, + 'aria-describedby': setDescriptionId(), + 'aria-required': required, id: uid, - disabled: disabled + disabled: disabled, + 'aria-invalid': error().length ? true : 'false' }" /> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html index 825a9869ec2..5cabf893190 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html @@ -10,7 +10,8 @@ attr: { name: inputName, placeholder: placeholder, - 'aria-describedby': noticeId, + 'aria-describedby': setDescriptionId(), + 'aria-required': required, id: uid, disabled: disabled }"/> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html index edd1395c5a7..3448ce42f9d 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html @@ -9,7 +9,8 @@ name: inputName, id: uid, disabled: disabled, - 'aria-describedby': noticeId, + 'aria-describedby': setDescriptionId(), + 'aria-required': required, placeholder: placeholder }, hasFocus: focused, diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html index 38d868a0f61..692f7d78a41 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html @@ -40,11 +40,11 @@ <!-- /ko --> <!-- ko if: element.error() --> - <div class="mage-error" data-bind="attr: { for: element.uid }, text: element.error" generated="true"></div> + <div class="mage-error" data-bind="attr: { id: element.errorId, for: element.uid }, text: element.error" generated="true"></div> <!-- /ko --> <!-- ko if: element.warn() --> - <div class="message warning" generated="true"><span data-bind="text: element.warn"></span></div> + <div class="message warning" data-bind="attr: { id: element.warningId }" generated="true"><span data-bind="text: element.warn"></span></div> <!-- /ko --> </div> </div> -- GitLab From be812d4413b5f9c86a4de58e478af6cfa5ccb2e9 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Mon, 25 Jul 2016 15:56:37 +0300 Subject: [PATCH 070/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - Checkout alert error message --- .../Magento/Ui/view/frontend/web/template/messages.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/frontend/web/template/messages.html b/app/code/Magento/Ui/view/frontend/web/template/messages.html index 5966523ec89..f0f03ec2e53 100644 --- a/app/code/Magento/Ui/view/frontend/web/template/messages.html +++ b/app/code/Magento/Ui/view/frontend/web/template/messages.html @@ -6,13 +6,13 @@ --> <div data-role="checkout-messages" class="messages" data-bind="visible: isVisible(), click: removeAll"> <!-- ko foreach: messageContainer.getErrorMessages() --> - <div class="message message-error error"> + <div role="alert" class="message message-error error"> <div data-ui-id="checkout-cart-validationmessages-message-error" data-bind="text: $data"></div> </div> <!--/ko--> <!-- ko foreach: messageContainer.getSuccessMessages() --> - <div class="message message-success success"> + <div role="alert" class="message message-success success"> <div data-ui-id="checkout-cart-validationmessages-message-success" data-bind="text: $data"></div> </div> <!--/ko--> -</div> \ No newline at end of file +</div> -- GitLab From 29e5d89fb74a2eb67e46e5bce11549f4aa902e51 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Tue, 26 Jul 2016 17:24:21 +0300 Subject: [PATCH 071/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - set focus on elements during form validation --- .../view/frontend/web/js/view/shipping.js | 64 ++++++++++++++++--- 1 file changed, 54 insertions(+), 10 deletions(-) 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 60691ab0e7b..5c99c179592 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 @@ -69,17 +69,17 @@ define( isNewAddressAdded: ko.observable(false), saveInAddressBook: 1, quoteIsVirtual: quote.isVirtual(), + fieldsetName: 'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset', /** * @return {exports} */ initialize: function () { var self = this, - hasNewAddress, - fieldsetName = 'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset'; + hasNewAddress; this._super(); - shippingRatesValidator.initFields(fieldsetName); + shippingRatesValidator.initFields(this.fieldsetName); if (!quote.isVirtual()) { stepNavigator.registerStep( @@ -239,7 +239,8 @@ define( var shippingAddress, addressData, loginFormSelector = 'form[data-role=email-with-possible-login]', - emailValidationResult = customer.isLoggedIn(); + emailValidationResult = customer.isLoggedIn(), + fieldset; if (!quote.shippingMethod()) { this.errorValidationMessage($.mage.__('Please specify a shipping method.')); @@ -256,16 +257,26 @@ define( this.source.set('params.invalid', false); this.source.trigger('shippingAddress.data.validate'); + // In case of form is invalid + // get first error and focus it + if (this.source.get('params.invalid')) { + fieldset = registry.get(this.fieldsetName); + if (fieldset && typeof fieldset.elems === 'function') { + this._focusFormErrors(fieldset.elems()); + } + } + if (this.source.get('shippingAddress.custom_attributes')) { this.source.trigger('shippingAddress.custom_attributes.data.validate'); } - if (this.source.get('params.invalid') || - !quote.shippingMethod().method_code || - !quote.shippingMethod().carrier_code || - !emailValidationResult - ) { - return false; + if (emailValidationResult) { + if (this.source.get('params.invalid') || + !quote.shippingMethod().method_code || + !quote.shippingMethod().carrier_code + ) { + return false; + } } shippingAddress = quote.shippingAddress(); @@ -302,6 +313,39 @@ define( } return true; + }, + + /** + * Recursive check collection of elements for errors and set related focus + * + * @param collection + * @returns {boolean} + * @private + */ + _focusFormErrors: function (collection) { + var i, + item, + skipCheck = false; + + for (i in collection) { + if (!collection.hasOwnProperty(i)) { + continue; + } + + item = collection[i]; + if (typeof item.elems === 'function') { + skipCheck = this._focusFormErrors(item.elems()); + } + + if (!skipCheck) { + if (typeof item.error === 'function' && item.error() && typeof item.focused === 'function') { + item.focused(true); + return true; + } + } + } + + return false; } }); } -- GitLab From 89e017dac0684748e59d45d41e194a09d6ab89de Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Wed, 27 Jul 2016 10:57:42 +0300 Subject: [PATCH 072/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - Create new error class for storefront - Add correct aria- attributes - Fix not translated text --- .../Ui/view/base/web/js/form/element/abstract.js | 11 +++++------ .../Ui/view/base/web/js/grid/editing/editor.js | 11 ++++++++++- .../Ui/view/base/web/templates/form/field.html | 2 +- .../web/templates/grid/editing/header-buttons.html | 4 ++-- .../web/templates/form/element/checkbox.html | 5 +++-- .../frontend/web/templates/form/element/date.html | 3 ++- .../frontend/web/templates/form/element/email.html | 5 +++-- .../frontend/web/templates/form/element/input.html | 6 +++--- .../web/templates/form/element/password.html | 3 ++- .../web/templates/form/element/select.html | 3 ++- .../Ui/view/frontend/web/templates/form/field.html | 14 ++++++++++---- .../Magento/blank/web/css/source/_forms.less | 5 +++++ .../Magento/luma/web/css/source/_forms.less | 5 +++++ 13 files changed, 53 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 7e03a59ab48..270e8a2c3a1 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -84,7 +84,7 @@ define([ this._super(); - this.observe('error disabled focused preview visible value warn isDifferedFromDefault') + this.observe('error disabled focused preview visible value warn notice isDifferedFromDefault') .observe('isUseDefault') .observe({ 'required': !!rules['required-entry'] @@ -115,7 +115,6 @@ define([ uid: uid, noticeId: 'notice-' + uid, errorId: 'error-' + uid, - warningId: 'warning-' + uid, inputName: utils.serializeName(name.join('.')), valueUpdate: valueUpdate }); @@ -443,14 +442,14 @@ define([ /** * Returns correct id for 'aria-describedby' accessibility attribute * - * @returns {String} + * @returns {Boolean|String} */ - setDescriptionId: function () { + getDescriptionId: function () { var id = false; - if(this.error().length > 0) { + if (this.error()) { id = this.errorId; - } else if (this.notice) { + } else if (this.notice()) { id = this.noticeId; } diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js index b39fb1a3718..47beec3de2f 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js @@ -486,7 +486,7 @@ define([ }, /** - * Counts number of invalid fields accros all active records. + * Counts number of invalid fields across all active records. * * @returns {Number} */ @@ -502,6 +502,15 @@ define([ return errorsCount; }, + /** + * Translatable error message text. + * + * @param {String} + */ + countErrorsMessage: function () { + return $t('There are {placeholder} messages requires your attention.'). replace('{placeholder}', this.countErrors()); + }, + /** * Checks if editor has any errors. * 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 60f902a42d9..4f20e2ba6ca 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 @@ -40,4 +40,4 @@ <render args="$data.service.template" if="$data.hasService()"/> </div> -</div> \ No newline at end of file +</div> diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html b/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html index 8ab4a8418c5..fd4e61108aa 100644 --- a/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html +++ b/app/code/Magento/Ui/view/base/web/templates/grid/editing/header-buttons.html @@ -9,8 +9,8 @@ class="data-grid-info-panel"> <div if="hasMessages() || hasErrors()" class="messages"> <div if="hasErrors()" class="message message-warning"> - <strong>There are <text args="countErrors()"/> messages requires your attention.</strong> - Please make corrections to the errors in the table below and re-submit. + <strong><text args="countErrorsMessage()"/></strong> + <span translate="'Please make corrections to the errors in the table below and re-submit.'"/> </div> <div class="message" outereach="messages" text="message" css=" diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html index c54cfdbe8e7..c22df869a00 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/checkbox.html @@ -13,8 +13,9 @@ id: uid, disabled: disabled, name: inputName, - 'aria-describedby': setDescriptionId(), - 'aria-required': required + 'aria-describedby': getDescriptionId(), + 'aria-required': required, + 'aria-invalid': error() ? true : 'false' }, hasFocus: focused"> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html index cebeeb636f5..48faf4b73a5 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/date.html @@ -11,7 +11,8 @@ value: value, name: inputName, placeholder: placeholder, - 'aria-describedby': setDescriptionId(), + 'aria-describedby': getDescriptionId(), 'aria-required': required, + 'aria-invalid': error() ? true : 'false', disabled: disabled }" /> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html index 9f11ba35bc7..57f94670323 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/email.html @@ -10,8 +10,9 @@ attr: { name: inputName, placeholder: placeholder, - 'aria-describedby': setDescriptionId(), - 'aria-required': required + 'aria-describedby': getDescriptionId(), + 'aria-required': required, + 'aria-invalid': error() ? true : 'false', id: uid, disabled: disabled }"/> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html index 0eee7c2cf23..a09e0383ef8 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html @@ -11,9 +11,9 @@ attr: { name: inputName, placeholder: placeholder, - 'aria-describedby': setDescriptionId(), + 'aria-describedby': getDescriptionId(), 'aria-required': required, + 'aria-invalid': error() ? true : 'false', id: uid, - disabled: disabled, - 'aria-invalid': error().length ? true : 'false' + disabled: disabled }" /> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html index 5cabf893190..0d93d48aa96 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/password.html @@ -10,8 +10,9 @@ attr: { name: inputName, placeholder: placeholder, - 'aria-describedby': setDescriptionId(), + 'aria-describedby': getDescriptionId(), 'aria-required': required, + 'aria-invalid': error() ? true : 'false', id: uid, disabled: disabled }"/> diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html index 3448ce42f9d..37d87d183e0 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/select.html @@ -9,8 +9,9 @@ name: inputName, id: uid, disabled: disabled, - 'aria-describedby': setDescriptionId(), + 'aria-describedby': getDescriptionId(), 'aria-required': required, + 'aria-invalid': error() ? true : 'false', placeholder: placeholder }, hasFocus: focused, diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html index 692f7d78a41..4405c79aa60 100644 --- a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html +++ b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html @@ -36,16 +36,22 @@ <!-- /ko --> <!-- ko if: element.notice --> - <div class="field-note" data-bind="attr: { id: element.noticeId }"><span data-bind="text: element.notice"></span></div> + <div class="field-note" data-bind="attr: { id: element.noticeId }"> + <span data-bind="text: element.notice"/> + </div> <!-- /ko --> <!-- ko if: element.error() --> - <div class="mage-error" data-bind="attr: { id: element.errorId, for: element.uid }, text: element.error" generated="true"></div> + <div class="field-error" data-bind="attr: { id: element.errorId }" generated="true"> + <span data-bind="text: element.error"/> + </div> <!-- /ko --> <!-- ko if: element.warn() --> - <div class="message warning" data-bind="attr: { id: element.warningId }" generated="true"><span data-bind="text: element.warn"></span></div> + <div role="alert" class="message warning" data-bind="attr: { id: element.warningId }" generated="true"> + <span data-bind="text: element.warn"/> + </div> <!-- /ko --> </div> </div> -<!-- /ko --> \ No newline at end of file +<!-- /ko --> diff --git a/app/design/frontend/Magento/blank/web/css/source/_forms.less b/app/design/frontend/Magento/blank/web/css/source/_forms.less index 72e014b8305..8c7258c390a 100644 --- a/app/design/frontend/Magento/blank/web/css/source/_forms.less +++ b/app/design/frontend/Magento/blank/web/css/source/_forms.less @@ -92,10 +92,15 @@ } } + .field-error, div.mage-error[generated] { margin-top: 7px; } + .field-error { + .lib-form-validation-note(); + } + .field .tooltip { .lib-tooltip(right); .tooltip-content { diff --git a/app/design/frontend/Magento/luma/web/css/source/_forms.less b/app/design/frontend/Magento/luma/web/css/source/_forms.less index 8d22eba9ca5..d29e53d7fef 100644 --- a/app/design/frontend/Magento/luma/web/css/source/_forms.less +++ b/app/design/frontend/Magento/luma/web/css/source/_forms.less @@ -113,10 +113,15 @@ .select-styling(); } + .field-error, div.mage-error[generated] { margin-top: 7px; } + .field-error { + .lib-form-validation-note(); + } + // TEMP .field .tooltip { -- GitLab From a5ba0bfc845929911e496f31c43d985c5c267f9c Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Wed, 27 Jul 2016 11:54:06 +0300 Subject: [PATCH 073/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront --- .../Magento/Checkout/view/frontend/web/template/shipping.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping.html index 9078731a855..47ec77759c1 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping.html @@ -141,7 +141,7 @@ <!-- /ko --> </div> <!-- ko if: errorValidationMessage().length > 0 --> - <div class="message notice"> + <div role="alert" class="message notice"> <span><!-- ko text: errorValidationMessage()--><!-- /ko --></span> </div> <!-- /ko --> -- GitLab From 9d7da5a0159f29783f845a9ce9924fad88f4b5cb Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Wed, 27 Jul 2016 15:54:18 +0300 Subject: [PATCH 074/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront --- .../view/frontend/templates/advanced/result.phtml | 2 +- .../Checkout/view/frontend/web/template/shipping.html | 2 +- .../Cookie/view/frontend/templates/html/notices.phtml | 11 ++++++++--- .../ImportExport/view/adminhtml/templates/busy.phtml | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml b/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml index b63acf736f9..3238f68401f 100644 --- a/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml +++ b/app/code/Magento/CatalogSearch/view/frontend/templates/advanced/result.phtml @@ -21,7 +21,7 @@ <?php endif; ?> </div> <?php else: ?> - <div class="message error"> + <div role="alert" class="message error"> <div> <?php /* @escapeNotVerified */ echo __('We can\'t find any items matching these search criteria.');?> <a href="<?php /* @escapeNotVerified */ echo $block->getFormUrl(); ?>"><?php /* @escapeNotVerified */ echo __('Modify your search.'); ?></a> </div> diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping.html index 47ec77759c1..5049aac2bbc 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping.html @@ -120,7 +120,7 @@ <!-- ko if: method.error_message --> <tr class="row row-error"> <td class="col col-error" colspan="4"> - <div class="message error"> + <div role="alert" class="message error"> <div data-bind="text: method.error_message"></div> </div> <span class="no-display"> diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 0ef6e395c03..f25e8b299fa 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -9,12 +9,17 @@ ?> <?php /** @var \Magento\Cookie\Block\Html\Notices $block */ ?> <?php if ($this->helper('Magento\Cookie\Helper\Cookie')->isUserNotAllowSaveCookie()): ?> - <div class="message global cookie" id="notice-cookie-block" style="display: none"> - <div class="content"> + <div role="alertdialog" + tabindex="-1" + class="message global cookie" + id="notice-cookie-block" + style="display: none;"> + <div role="document" class="content" tabindex="0"> <p> <strong><?php /* @escapeNotVerified */ echo __('We use cookies to make your experience better.') ?></strong> <span><?php /* @escapeNotVerified */ echo __('To comply with the new e-Privacy directive, we need to ask for your consent to set the cookies.') ?></span> - <?php /* @escapeNotVerified */ echo __('<a href="%1">Learn more</a>.', $block->getPrivacyPolicyLink()) ?></p> + <?php /* @escapeNotVerified */ echo __('<a href="%1">Learn more</a>.', $block->getPrivacyPolicyLink()) ?> + </p> <div class="actions"> <button id="btn-cookie-allow" class="action allow primary"> <span><?php /* @escapeNotVerified */ echo __('Allow Cookies');?></span> diff --git a/app/code/Magento/ImportExport/view/adminhtml/templates/busy.phtml b/app/code/Magento/ImportExport/view/adminhtml/templates/busy.phtml index cd77de6c78d..5e6e0b8e9ab 100644 --- a/app/code/Magento/ImportExport/view/adminhtml/templates/busy.phtml +++ b/app/code/Magento/ImportExport/view/adminhtml/templates/busy.phtml @@ -10,7 +10,7 @@ </div><br> <div class="messages"> <div class="message message-success success"> - <div><?php /* @escapeNotVerified */ echo $block->getStatusMessage(); ?>hh</div> + <div><?php /* @escapeNotVerified */ echo $block->getStatusMessage(); ?></div> </div> </div> </div> -- GitLab From 18b5d6df7afb16f6f6b6255eb5459a4df646f4f8 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Wed, 27 Jul 2016 17:54:49 -0500 Subject: [PATCH 075/838] MAGETWO-54580: [Github][PR] added partial fix for issue #2617. #3688 - Added message to clarify and prevent future changes. --- app/code/Magento/Newsletter/Model/Subscriber.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index cefab246408..86fc4e2d65e 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -442,6 +442,7 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel $this->setStatusChanged(true); try { + /* Save model before sending out email */ $this->save(); if ($isConfirmNeed === true && $isOwnSubscribes === false -- GitLab From 6e1b24dd1119fce84c11e00de68753438388a1be Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 28 Jul 2016 19:00:39 +0300 Subject: [PATCH 076/838] MAGETWO-56008: Moving getStoreByWebsite to Store Module --- .../Api/StoreWebsiteRelationInterface.php | 21 ++++++ .../ResourceModel/StoreWebsiteRelation.php | 42 +++++++++++ app/code/Magento/Store/Model/StoreManager.php | 23 +++++- .../StoreWebsiteRelationTest.php | 70 +++++++++++++++++++ app/code/Magento/Store/etc/di.xml | 1 + 5 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php create mode 100644 app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php create mode 100644 app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreWebsiteRelationTest.php diff --git a/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php b/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php new file mode 100644 index 00000000000..bcb9293c762 --- /dev/null +++ b/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Store\Api; + +/** + * @api + */ + +interface StoreWebsiteRelationInterface +{ + /** + * Get assigned to website store + * + * @param $websiteId + * @return array + */ + public function getStoreByWebsiteId($websiteId); +} diff --git a/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php b/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php new file mode 100644 index 00000000000..2ad62dfb172 --- /dev/null +++ b/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Store\Model\ResourceModel; +use Magento\Framework\App\ResourceConnection; + +/** + * Store Website Relation Resource Model + */ +class StoreWebsiteRelation +{ + /** @var ResourceConnection */ + private $resource; + + /** + * StoreWebsiteRelation constructor. + * @param ResourceConnection $resource + */ + public function __construct( + ResourceConnection $resource + ) { + $this->resource = $resource; + } + + /** + * @param int $websiteId + * @return array + */ + public function getStoreByWebsiteId($websiteId) + { + $connection = $this->resource->getConnection(); + $storeTable = $this->resource->getTableName('store'); + $storeSelect = $connection->select()->from($storeTable, ['store_id'])->where( + 'website_id = ?', + $websiteId + ); + $data = $connection->fetchCol($storeSelect); + return $data; + } +} diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 77532f2188c..6f68da6eb07 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -5,12 +5,16 @@ */ namespace Magento\Store\Model; +use Magento\Framework\App\ObjectManager; use Magento\Store\Api\StoreResolverInterface; +use Magento\Store\Model\ResourceModel\StoreWebsiteRelation; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class StoreManager implements \Magento\Store\Model\StoreManagerInterface +class StoreManager implements + \Magento\Store\Model\StoreManagerInterface, + \Magento\Store\Api\StoreWebsiteRelationInterface { /** * Application run code @@ -286,4 +290,21 @@ class StoreManager implements \Magento\Store\Model\StoreManagerInterface \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); } + + /** + * @deprecated + * @return StoreWebsiteRelation + */ + public function getStoreWebsiteRelation() + { + return ObjectManager::getInstance()->get(StoreWebsiteRelation::class); + } + + /** + * @inheritdoc + */ + public function getStoreByWebsiteId($websiteId) + { + return $this->getStoreWebsiteRelation()->getStoreByWebsiteId($websiteId); + } } diff --git a/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreWebsiteRelationTest.php b/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreWebsiteRelationTest.php new file mode 100644 index 00000000000..fbf8f5aa3d8 --- /dev/null +++ b/app/code/Magento/Store/Test/Unit/Model/ResourceModel/StoreWebsiteRelationTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Store\Test\Unit\Model\ResourceModel; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; +use Magento\Store\Model\ResourceModel\StoreWebsiteRelation; + +class StoreWebsiteRelationTest extends \PHPUnit_Framework_TestCase +{ + /** @var StoreWebsiteRelation */ + private $model; + + /** @var ResourceConnection | \PHPUnit_Framework_MockObject_MockObject */ + private $resourceConnection; + + /** @var AdapterInterface | \PHPUnit_Framework_MockObject_MockObject */ + private $connection; + + /** @var Select | \PHPUnit_Framework_MockObject_MockObject */ + private $select; + + public function setUp() + { + $this->select = $this->getMockBuilder(Select::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resourceConnection = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->connection = $this->getMock(AdapterInterface::class); + + $this->model = new StoreWebsiteRelation($this->resourceConnection); + } + + public function testGetStoreByWebsiteId() + { + $data = ['ololo']; + $websiteId = 1; + $storeTable = 'store'; + $this->resourceConnection->expects($this->once()) + ->method('getConnection') + ->willReturn($this->connection); + $this->resourceConnection->expects($this->once()) + ->method('getTableName') + ->willReturn($storeTable); + $this->connection->expects($this->once()) + ->method('select') + ->willReturn($this->select); + + $this->select->expects($this->once()) + ->method('from') + ->with($storeTable, ['store_id']) + ->willReturn($this->select); + $this->select->expects($this->once()) + ->method('where') + ->with('website_id = ?', $websiteId) + ->willReturn($this->select); + $this->connection->expects($this->once()) + ->method('fetchCol') + ->willReturn($data); + + $this->assertEquals($data, $this->model->getStoreByWebsiteId($websiteId)); + } +} diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index 3e9192c24d5..57bf057af27 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -12,6 +12,7 @@ <preference for="Magento\Store\Api\Data\StoreInterface" type="Magento\Store\Model\Store"/> <preference for="Magento\Store\Api\Data\GroupInterface" type="Magento\Store\Model\Group"/> <preference for="Magento\Store\Api\Data\WebsiteInterface" type="Magento\Store\Model\Website"/> + <preference for="Magento\Store\Api\StoreWebsiteRelationInterface" type="Magento\Store\Model\StoreManager"/> <preference for="Magento\Store\Api\StoreResolverInterface" type="Magento\Store\Model\StoreResolver"/> <preference for="Magento\Framework\App\Request\PathInfoProcessorInterface" type="Magento\Store\App\Request\PathInfoProcessor" /> <preference for="Magento\Store\Model\StoreManagerInterface" type="Magento\Store\Model\StoreManager" /> -- GitLab From d54c72584d15fd255bf504f1d9dff377cf559549 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 28 Jul 2016 19:20:58 +0300 Subject: [PATCH 077/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../FilterProcessor/CategoryFilter.php | 32 +++++ .../Catalog/Model/ProductRepository.php | 45 ++++--- app/code/Magento/Catalog/etc/di.xml | 21 ++++ .../ResourceModel/CustomerRepository.php | 49 +++++--- .../Model/ResourceModel/GroupRepository.php | 54 ++++---- app/code/Magento/Customer/etc/di.xml | 31 +++++ .../CollectionProcessor/FilterProcessor.php | 118 ++++++++++++++++++ app/code/Magento/Eav/etc/di.xml | 9 ++ app/etc/di.xml | 10 ++ .../CollectionProcessor/FilterProcessor.php | 118 ++++++++++++++++++ .../FilterProcessor/CustomFilterInterface.php | 24 ++++ .../PaginationProcessor.php | 26 ++++ .../CollectionProcessor/SortingProcessor.php | 97 ++++++++++++++ .../CollectionProcessorComposite.php | 41 ++++++ .../CollectionProcessorInterface.php | 24 ++++ 15 files changed, 640 insertions(+), 59 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php create mode 100644 app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CustomFilterInterface.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/PaginationProcessor.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php diff --git a/app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php b/app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php new file mode 100644 index 00000000000..48448128a28 --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class CategoryFilter implements CustomFilterInterface +{ + /** + * Apply category_id Filter to Product Collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool Whether the filter is applied + */ + public function apply(Filter $filter, AbstractDb $collection) + { + $conditionType = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; + $categoryFilter = [$conditionType => [$filter->getValue()]]; + + /** @var Collection $collection */ + $collection->addCategoriesFilter($categoryFilter); + + return true; + } +} diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 7d701d60c65..750cdd6a4bd 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -13,7 +13,7 @@ use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\Api\Data\ImageContentInterfaceFactory; use Magento\Framework\Api\ImageContentValidatorInterface; use Magento\Framework\Api\ImageProcessorInterface; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; @@ -132,6 +132,11 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa */ protected $mediaGalleryProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * ProductRepository constructor. * @param ProductFactory $productFactory @@ -154,6 +159,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa * @param MimeTypeExtensionMap $mimeTypeExtensionMap * @param ImageProcessorInterface $imageProcessor * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param CollectionProcessorInterface $collectionProcessor * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -177,7 +183,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa ImageContentInterfaceFactory $contentFactory, MimeTypeExtensionMap $mimeTypeExtensionMap, ImageProcessorInterface $imageProcessor, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->productFactory = $productFactory; $this->collectionFactory = $collectionFactory; @@ -196,6 +203,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa $this->contentFactory = $contentFactory; $this->imageProcessor = $imageProcessor; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -600,20 +608,8 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner'); $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner'); - //Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - /** @var SortOrder $sortOrder */ - foreach ((array)$searchCriteria->getSortOrders() as $sortOrder) { - $field = $sortOrder->getField(); - $collection->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $this->collectionProcessor->process($searchCriteria, $collection); + $collection->load(); $searchResult = $this->searchResultsFactory->create(); @@ -626,6 +622,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa /** * Helper function that adds a FilterGroup to the collection. * + * @deprecated * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup * @param Collection $collection * @return void @@ -677,4 +674,20 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa } return $this->mediaGalleryProcessor; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 258602d8457..2528796ad75 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -792,4 +792,25 @@ </argument> </arguments> </type> + <virtualType name="Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="category_id" xsi:type="object">Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CategoryFilter</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Catalog\Model\ProductRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessorComposite</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index 11490f6d421..f34dc0f4ac5 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -9,8 +9,8 @@ namespace Magento\Customer\Model\ResourceModel; use Magento\Customer\Api\CustomerMetadataInterface; 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\SortOrder; /** * Customer repository. @@ -83,6 +83,11 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte */ protected $extensionAttributesJoinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param \Magento\Customer\Model\CustomerFactory $customerFactory * @param \Magento\Customer\Model\Data\CustomerSecureFactory $customerSecureFactory @@ -97,6 +102,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte * @param DataObjectHelper $dataObjectHelper * @param ImageProcessorInterface $imageProcessor * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param CollectionProcessorInterface $collectionProcessor * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -112,7 +118,8 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter, DataObjectHelper $dataObjectHelper, ImageProcessorInterface $imageProcessor, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->customerFactory = $customerFactory; $this->customerSecureFactory = $customerSecureFactory; @@ -127,6 +134,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte $this->dataObjectHelper = $dataObjectHelper; $this->imageProcessor = $imageProcessor; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -286,23 +294,11 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left') ->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left') ->joinAttribute('company', 'customer_address/company', 'default_billing', null, 'left'); - //Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } + + $this->collectionProcessor->process($searchCriteria, $collection); + $searchResults->setTotalCount($collection->getSize()); - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders) { - /** @var SortOrder $sortOrder */ - foreach ($searchCriteria->getSortOrders() as $sortOrder) { - $collection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $customers = []; /** @var \Magento\Customer\Model\Customer $customerModel */ foreach ($collection as $customerModel) { @@ -334,6 +330,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte /** * Helper function that adds a FilterGroup to the collection. * + * @deprecated * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup * @param \Magento\Customer\Model\ResourceModel\Customer\Collection $collection * @return void @@ -352,4 +349,20 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte $collection->addFieldToFilter($fields); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php b/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php index 9ef17cb2568..2dcd0432d2b 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php @@ -10,7 +10,7 @@ use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Model\ResourceModel\Group\Collection; use Magento\Framework\Api\Search\FilterGroup; use Magento\Framework\Api\SearchCriteriaInterface; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\State\InvalidTransitionException; use Magento\Tax\Api\Data\TaxClassInterface; @@ -70,6 +70,11 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface */ protected $extensionAttributesJoinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param \Magento\Customer\Model\GroupRegistry $groupRegistry * @param \Magento\Customer\Model\GroupFactory $groupFactory @@ -79,6 +84,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface * @param \Magento\Customer\Api\Data\GroupSearchResultsInterfaceFactory $searchResultsFactory * @param \Magento\Tax\Api\TaxClassRepositoryInterface $taxClassRepositoryInterface * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( \Magento\Customer\Model\GroupRegistry $groupRegistry, @@ -88,7 +94,8 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor, \Magento\Customer\Api\Data\GroupSearchResultsInterfaceFactory $searchResultsFactory, \Magento\Tax\Api\TaxClassRepositoryInterface $taxClassRepositoryInterface, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->groupRegistry = $groupRegistry; $this->groupFactory = $groupFactory; @@ -98,6 +105,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface $this->searchResultsFactory = $searchResultsFactory; $this->taxClassRepository = $taxClassRepositoryInterface; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -179,29 +187,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface $this->extensionAttributesJoinProcessor->process($collection, $groupInterfaceName); $collection->addTaxClass(); - //Add filters from root filter group to the collection - /** @var FilterGroup $group */ - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - $sortOrders = $searchCriteria->getSortOrders(); - /** @var SortOrder $sortOrder */ - if ($sortOrders) { - foreach ($searchCriteria->getSortOrders() as $sortOrder) { - $field = $this->translateField($sortOrder->getField()); - $collection->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } else { - // set a default sorting order since this method is used constantly in many - // different blocks - $field = $this->translateField('id'); - $collection->addOrder($field, 'ASC'); - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $this->collectionProcessor->process($searchCriteria, $collection); /** @var \Magento\Customer\Api\Data\GroupInterface[] $groups */ $groups = []; @@ -229,6 +215,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface /** * Helper function that adds a FilterGroup to the collection. * + * @deprecated * @param FilterGroup $filterGroup * @param Collection $collection * @return void @@ -251,6 +238,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface /** * Translates a field name to a DB column name for use in collection queries. * + * @deprecated * @param string $field a field name that should be translated to a DB column name. * @return string */ @@ -345,4 +333,20 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface throw InputException::invalidFieldValue('taxClassId', $group->getTaxClassId()); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index bb6577470ba..e47ee111e89 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -315,4 +315,35 @@ <argument name="cache" xsi:type="object">Magento\Customer\Model\Cache\Type\Notification</argument> </arguments> </type> + <type name="Magento\Customer\Model\ResourceModel\CustomerRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> + </arguments> + </type> + <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\SortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> + <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="code" xsi:type="string">customer_group_code</item> + <item name="id" xsi:type="string">customer_group_id</item> + <item name="tax_class_name" xsi:type="string">class_name</item> + </argument> + <argument name="defaultOrders" xsi:type="array"> + <item name="id" xsi:type="string">ASC</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Customer\Model\ResourceModel\GroupRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php new file mode 100644 index 00000000000..2eaca95022d --- /dev/null +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class FilterProcessor implements CollectionProcessorInterface +{ + /** + * @var CustomFilterInterface[] + */ + private $customFilters; + + /** + * @var array + */ + private $fieldMapping; + + /** + * @param CustomFilterInterface[] $customFilters + * @param array $fieldMapping + */ + public function __construct( + array $customFilters = [], + array $fieldMapping = [] + ) { + $this->customFilters = $customFilters; + $this->fieldMapping = $fieldMapping; + } + + /** + * Apply Search Criteria Filters to collection + * + * @param SearchCriteriaInterface $searchCriteria + * @param AbstractDb $collection + * @return void + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) + { + foreach ($searchCriteria->getFilterGroups() as $group) { + $this->addFilterGroupToCollection($group, $collection); + } + } + + /** + * Add FilterGroup to the collection + * + * @param FilterGroup $filterGroup + * @param AbstractDb $collection + */ + private function addFilterGroupToCollection( + FilterGroup $filterGroup, + AbstractDb $collection + ) { + $fields = []; + foreach ($filterGroup->getFilters() as $filter) { + $isApplied = false; + $customFilter = $this->getCustomFilterForField($filter->getField()); + if ($customFilter) { + $isApplied = $customFilter->apply($filter, $collection); + } + + if (!$isApplied) { + $field = $this->getFieldMapping($filter->getField()); + $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; + $fields[] = ['attribute' => $field, $condition => $filter->getValue()]; + } + } + + if ($fields) { + $collection->addFieldToFilter($fields); + } + } + + + /** + * Return custom filters for field if exists + * + * @param string $field + * @return CustomFilterInterface|null + * @throws \InvalidArgumentException + */ + private function getCustomFilterForField($field) + { + $filter = null; + if (isset($this->customFilters[$field])) { + $filter = $this->customFilters[$field]; + if (!($this->customFilters[$field] instanceof CustomFilterInterface)) { + throw new \InvalidArgumentException( + sprintf( + 'Filter for %s must implement %s interface.', + $field, + CustomFilterInterface::class + ) + ); + } + } + return $filter; + } + + /** + * Return mapped field name + * + * @param string $field + * @return string + */ + private function getFieldMapping($field) + { + return isset($this->fieldMapping[$field]) ? $this->fieldMapping[$field] : $field; + } +} diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index ae230ca193a..4dd117bbc29 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -82,5 +82,14 @@ <type name="Magento\Eav\Model\Entity\AbstractEntity"> <plugin name="clean_cache" type="Magento\Framework\App\Cache\FlushCacheByTags" /> </type> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> </config> diff --git a/app/etc/di.xml b/app/etc/di.xml index 5836e5314b4..c847699543f 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1207,4 +1207,14 @@ </argument> </arguments> </type> + <preference for="Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite" /> + <type name="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </type> </config> diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php new file mode 100644 index 00000000000..0cfac2a3adb --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class FilterProcessor implements CollectionProcessorInterface +{ + /** + * @var CustomFilterInterface[] + */ + private $customFilters; + + /** + * @var array + */ + private $fieldMapping; + + /** + * @param CustomFilterInterface[] $customFilters + * @param array $fieldMapping + */ + public function __construct( + array $customFilters = [], + array $fieldMapping = [] + ) { + $this->customFilters = $customFilters; + $this->fieldMapping = $fieldMapping; + } + + /** + * Apply Search Criteria Filters to collection + * + * @param SearchCriteriaInterface $searchCriteria + * @param AbstractDb $collection + * @return void + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) + { + foreach ($searchCriteria->getFilterGroups() as $group) { + $this->addFilterGroupToCollection($group, $collection); + } + } + + /** + * Add FilterGroup to the collection + * + * @param FilterGroup $filterGroup + * @param AbstractDb $collection + */ + private function addFilterGroupToCollection( + FilterGroup $filterGroup, + AbstractDb $collection + ) { + $fields = []; + $conditions = []; + foreach ($filterGroup->getFilters() as $filter) { + $isApplied = false; + $customFilter = $this->getCustomFilterForField($filter->getField()); + if ($customFilter) { + $isApplied = $customFilter->apply($filter, $collection); + } + + if (!$isApplied) { + $field = $this->getFieldMapping($filter->getField()); + $fields[$field] = $filter->getValue(); + $conditions[$field] = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; + } + } + + if ($fields) { + $collection->addFieldToFilter($fields, $conditions); + } + } + + /** + * Return custom filters for field if exists + * + * @param string $field + * @return CustomFilterInterface|null + * @throws \InvalidArgumentException + */ + private function getCustomFilterForField($field) + { + $filter = null; + if (isset($this->customFilters[$field])) { + $filter = $this->customFilters[$field]; + if (!($this->customFilters[$field] instanceof CustomFilterInterface)) { + throw new \InvalidArgumentException( + sprintf( + 'Filter for %s must implement %s interface.', + $field, + CustomFilterInterface::class + ) + ); + } + } + return $filter; + } + + /** + * Return mapped field name + * + * @param string $field + * @return string + */ + private function getFieldMapping($field) + { + return isset($this->fieldMapping[$field]) ? $this->fieldMapping[$field] : $field; + } +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CustomFilterInterface.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CustomFilterInterface.php new file mode 100644 index 00000000000..63755d061a9 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CustomFilterInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * @api + */ +interface CustomFilterInterface +{ + /** + * Apply Custom Filter to Collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool Whether the filter was applied + */ + public function apply(Filter $filter, AbstractDb $collection); +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/PaginationProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/PaginationProcessor.php new file mode 100644 index 00000000000..781bbc7b92f --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/PaginationProcessor.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class PaginationProcessor implements CollectionProcessorInterface +{ + /** + * Apply Search Criteria Pagination to collection + * + * @param SearchCriteriaInterface $searchCriteria + * @param AbstractDb $collection + * @return void + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) + { + $collection->setCurPage($searchCriteria->getCurrentPage()); + $collection->setPageSize($searchCriteria->getPageSize()); + } +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php new file mode 100644 index 00000000000..29a9240073d --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Data\Collection; +use Magento\Framework\Data\Collection\AbstractDb; + +class SortingProcessor implements CollectionProcessorInterface +{ + /** + * @var array + */ + private $fieldMapping; + + /** + * @var array + */ + private $defaultOrders; + + /** + * @param array $fieldMapping + * @param array $defaultOrders + */ + public function __construct( + array $fieldMapping = [], + array $defaultOrders = [] + ) { + $this->fieldMapping = $fieldMapping; + $this->defaultOrders = $defaultOrders; + } + + /** + * Apply Search Criteria Sorting Orders to collection + * + * @param SearchCriteriaInterface $searchCriteria + * @param AbstractDb $collection + * @return void + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) + { + if ($searchCriteria->getSortOrders()) { + $this->applyOrders($searchCriteria->getSortOrders(), $collection); + } elseif ($this->defaultOrders) { + $this->applyDefaultOrders($collection); + } + } + + /** + * Return mapped field name + * + * @param string $field + * @return string + */ + private function getFieldMapping($field) + { + return isset($this->fieldMapping[$field]) ? $this->fieldMapping[$field] : $field; + } + + /** + * Apply sort orders to collection + * + * @param SortOrder[] $sortOrders + * @param AbstractDb $collection + */ + private function applyOrders(array $sortOrders, AbstractDb $collection) + { + /** @var SortOrder $sortOrder */ + foreach ($sortOrders as $sortOrder) { + $field = $this->getFieldMapping($sortOrder->getField()); + $order = $sortOrder->getDirection() == SortOrder::SORT_ASC + ? Collection::SORT_ORDER_ASC + : Collection::SORT_ORDER_DESC; + $collection->addOrder($field, $order); + } + } + + /** + * Apply default orders to collection + * + * @param AbstractDb $collection + */ + private function applyDefaultOrders(AbstractDb $collection) + { + foreach ($this->defaultOrders as $field => $direction) { + $order = $direction == SortOrder::SORT_ASC + ? Collection::SORT_ORDER_ASC + : Collection::SORT_ORDER_DESC; + $collection->addOrder($field, $order); + } + } +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php new file mode 100644 index 00000000000..acc6b802fb2 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria; + +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class CollectionProcessorComposite implements CollectionProcessorInterface +{ + /** + * @var CollectionProcessorInterface[] + */ + private $processors; + + /** + * @param CollectionProcessorInterface[] $processors + */ + public function __construct( + array $processors + ) { + $this->processors = $processors; + } + + /** + * @inheritDoc + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) + { + foreach ($this->processors as $processor) { + if (!($processor instanceof CollectionProcessorInterface)) { + throw new \InvalidArgumentException( + sprintf('Processor must implement %s interface.', CollectionProcessorInterface::class) + ); + } + $processor->process($searchCriteria, $collection); + } + } +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php new file mode 100644 index 00000000000..8fdd244f9b4 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria; + +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * @api + */ +interface CollectionProcessorInterface +{ + /** + * Apply Search Criteria to Collection + * + * @param SearchCriteriaInterface $searchCriteria + * @param AbstractDb $collection + * @throws \InvalidArgumentException + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection); +} -- GitLab From 15d9fa1ab8e691b31f1e5ddacb091fc12eb16a0d Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Fri, 29 Jul 2016 12:11:28 +0300 Subject: [PATCH 078/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../Test/Unit/Model/ProductRepositoryTest.php | 73 ++----- .../ResourceModel/CustomerRepositoryTest.php | 59 ++---- .../ResourceModel/GroupRepositoryTest.php | 197 ++---------------- app/code/Magento/Customer/etc/di.xml | 11 +- .../CollectionProcessor/FilterProcessor.php | 2 +- .../CollectionProcessor/FilterProcessor.php | 11 +- .../CollectionProcessor/SortingProcessor.php | 3 + .../CollectionProcessorInterface.php | 1 + 8 files changed, 68 insertions(+), 289 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index 5e99fd46757..f33b0935f2d 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -9,11 +9,10 @@ namespace Magento\Catalog\Test\Unit\Model; -use Magento\Catalog\Model\Layer\Filter\Dynamic\AlgorithmFactory; +use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Framework\Api\Data\ImageContentInterface; -use Magento\Framework\Api\SortOrder; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\Store\Model\ScopeInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * Class ProductRepositoryTest @@ -141,12 +140,16 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $mediaGalleryProcessor; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function setUp() { - $this->markTestSkipped('11111111111111111111111'); $this->productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create'], [], '', false); $this->productMock = $this->getMock( @@ -270,6 +273,9 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase false ); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + $this->model = $this->objectManager->getObject( 'Magento\Catalog\Model\ProductRepository', [ @@ -289,7 +295,8 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase 'linkTypeProvider' => $this->linkTypeProviderMock, 'imageProcessor' => $this->imageProcessorMock, 'storeManager' => $this->storeManagerMock, - 'mediaGalleryProcessor' => $this->mediaGalleryProcessor + 'mediaGalleryProcessor' => $this->mediaGalleryProcessor, + 'collectionProcessor' => $this->collectionProcessorMock ] ); } @@ -351,7 +358,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->productFactoryMock->expects($this->once())->method('create') ->will($this->returnValue($this->productMock)); $this->productMock->expects($this->once())->method('load')->with('product_id'); - $this->productMock->expects($this->once())->method('getWebsiteIds'); $this->productMock->expects($this->once())->method('getId')->willReturn(null); $this->model->getById('product_id'); } @@ -363,7 +369,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($this->productMock)); $this->productMock->expects($this->once())->method('setData')->with('_edit_mode', true); $this->productMock->expects($this->once())->method('load')->with($productId); - $this->productMock->expects($this->once())->method('getWebsiteIds'); $this->productMock->expects($this->once())->method('getId')->willReturn($productId); $this->assertEquals($this->productMock, $this->model->getById($productId, true)); } @@ -409,7 +414,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->productFactoryMock->expects($this->exactly(2))->method('create') ->will($this->returnValue($this->productMock)); $this->productMock->expects($this->exactly(2))->method('load'); - $this->productMock->expects($this->exactly(2))->method('getWebsiteIds'); $this->productMock->expects($this->exactly(2))->method('getId')->willReturn($identifier); $this->assertEquals($this->productMock, $this->model->getById($identifier, $editMode, $storeId)); //second invocation should just return from cache @@ -433,7 +437,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->productFactoryMock->expects($this->exactly(2))->method('create') ->will($this->returnValue($this->productMock)); $this->productMock->expects($this->exactly(2))->method('load'); - $this->productMock->expects($this->exactly(2))->method('getWebsiteIds'); $this->productMock->expects($this->exactly(2))->method('getId')->willReturn($sku); $this->resourceModelMock->expects($this->exactly(2))->method('getIdBySku') ->with($sku)->willReturn($id); @@ -452,7 +455,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($this->productMock)); $this->productMock->expects($this->once())->method('setData')->with('store_id', $storeId); $this->productMock->expects($this->once())->method('load')->with($productId); - $this->productMock->expects($this->once())->method('getWebsiteIds'); $this->productMock->expects($this->once())->method('getId')->willReturn($productId); $this->assertEquals($this->productMock, $this->model->getById($productId, false, $storeId)); } @@ -464,7 +466,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->productFactoryMock->expects($this->once())->method('create') ->will($this->returnValue($this->productMock)); $this->productMock->expects($this->once())->method('load')->with($productId); - $this->productMock->expects($this->once())->method('getWebsiteIds'); $this->productMock->expects($this->once())->method('getId')->willReturn($productId); $this->productMock->expects($this->once())->method('getSku')->willReturn($productSku); $this->assertEquals($this->productMock, $this->model->getById($productId)); @@ -624,15 +625,10 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $attributeCode = 'attribute_code'; $collectionMock = $this->getMock('\Magento\Catalog\Model\ResourceModel\Product\Collection', [], [], '', false); $extendedSearchCriteriaMock = $this->getMock('\Magento\Framework\Api\SearchCriteria', [], [], '', false); - $productAttributeSearchResultsMock = $this->getMockForAbstractClass( - '\Magento\Catalog\Api\Data\ProductAttributeInterface', - [], - '', - false, - false, - false, - ['getItems'] - ); + $productAttributeSearchResultsMock = $this->getMockBuilder(ProductAttributeInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getItems']) + ->getMockForAbstractClass(); $productAttributeMock = $this->getMock( '\Magento\Catalog\Api\Data\ProductAttributeInterface', [], @@ -640,9 +636,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - $filterGroupMock = $this->getMock('\Magento\Framework\Api\Search\FilterGroup', [], [], '', false); - $filterGroupFilterMock = $this->getMock('\Magento\Framework\Api\Filter', [], [], '', false); - $sortOrderMock = $this->getMock('\Magento\Framework\Api\SortOrder', [], [], '', false); $itemsMock = $this->getMock('\Magento\Framework\DataObject', [], [], '', false); $this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock); @@ -658,21 +651,9 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase ['status', 'catalog_product/status', 'entity_id', null, 'inner'], ['visibility', 'catalog_product/visibility', 'entity_id', null, 'inner'] ); - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]); - $filterGroupMock->expects($this->once())->method('getFilters')->willReturn([$filterGroupFilterMock]); - $filterGroupFilterMock->expects($this->exactly(2))->method('getConditionType')->willReturn('eq'); - $filterGroupFilterMock->expects($this->atLeastOnce())->method('getField')->willReturn($fieldName); - $filterGroupFilterMock->expects($this->once())->method('getValue')->willReturn('value'); - $this->expectAddToFilter($fieldName, $collectionMock); - $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]); - $sortOrderMock->expects($this->atLeastOnce())->method('getField')->willReturn($fieldName); - $sortOrderMock->expects($this->once())->method('getDirection') - ->willReturn(SortOrder::SORT_ASC); - $collectionMock->expects($this->once())->method('addOrder')->with($fieldName, 'ASC'); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn(4); - $collectionMock->expects($this->once())->method('setCurPage')->with(4); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn(42); - $collectionMock->expects($this->once())->method('setPageSize')->with(42); + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $collectionMock->expects($this->once())->method('load'); $collectionMock->expects($this->once())->method('getItems')->willReturn([$itemsMock]); $collectionMock->expects($this->once())->method('getSize')->willReturn(128); @@ -1258,22 +1239,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expectedResult, $this->initializedProductMock->getMediaGallery('images')); } - /** - * @param $fieldName - * @param $collectionMock - * @return void - */ - public function expectAddToFilter($fieldName, $collectionMock) - { - if ($fieldName == 'category_id') { - $collectionMock->expects($this->once())->method('addCategoriesFilter') - ->with(['eq' => ['value']]); - } else { - $collectionMock->expects($this->once())->method('addFieldToFilter') - ->with([['attribute' => $fieldName, 'eq' => 'value']]); - } - } - /** * @return array */ diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php index a2b285fc0db..9104d0a7359 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php @@ -7,6 +7,7 @@ namespace Magento\Customer\Test\Unit\Model\ResourceModel; use Magento\Customer\Api\CustomerMetadataInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -83,6 +84,11 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $customer; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + /** * @var \Magento\Customer\Model\ResourceModel\CustomerRepository */ @@ -161,6 +167,8 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); $this->model = new \Magento\Customer\Model\ResourceModel\CustomerRepository( $this->customerFactory, @@ -175,7 +183,8 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase $this->extensibleDataObjectConverter, $this->dataObjectHelper, $this->imageProcessor, - $this->extensionAttributesJoinProcessor + $this->extensionAttributesJoinProcessor, + $this->collectionProcessorMock ); } @@ -654,9 +663,6 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetList() { - $sortOrder = $this->getMock('Magento\Framework\Api\SortOrder', [], [], '', false); - $filterGroup = $this->getMock('Magento\Framework\Api\Search\FilterGroup', [], [], '', false); - $filter = $this->getMock('Magento\Framework\Api\Filter', [], [], '', false); $collection = $this->getMock('Magento\Customer\Model\ResourceModel\Customer\Collection', [], [], '', false); $searchResults = $this->getMockForAbstractClass( 'Magento\Customer\Api\Data\AddressSearchResultsInterface', @@ -746,48 +752,9 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase ->method('joinAttribute') ->with('company', 'customer_address/company', 'default_billing', null, 'left') ->willReturnSelf(); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroup]); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->with([['attribute' => 'Field', 'eq' => 'Value']]); - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $filter->expects($this->once()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->once()) - ->method('getField') - ->willReturn('Field'); - $filter->expects($this->atLeastOnce()) - ->method('getValue') - ->willReturn('Value'); - $collection->expects($this->once()) - ->method('addOrder') - ->with('Field', 'ASC'); - $searchCriteria->expects($this->atLeastOnce()) - ->method('getSortOrders') - ->willReturn([$sortOrder]); - $sortOrder->expects($this->once()) - ->method('getField') - ->willReturn('Field'); - $sortOrder->expects($this->once()) - ->method('getDirection') - ->willReturn(\Magento\Framework\Api\SortOrder::SORT_ASC); - $searchCriteria->expects($this->once()) - ->method('getCurrentPage') - ->willReturn(1); - $collection->expects($this->once()) - ->method('setCurPage') - ->with(1); - $searchCriteria->expects($this->once()) - ->method('getPageSize') - ->willReturn(10); - $collection->expects($this->once()) - ->method('setPageSize') - ->with(10); + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $collection->expects($this->once()) ->method('getSize') ->willReturn(23); diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php index 3efab84320e..ecc1b4f6ec2 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php @@ -6,6 +6,8 @@ namespace Magento\Customer\Test\Unit\Model\ResourceModel; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -66,6 +68,11 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $extensionAttributesJoinProcessor; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + /** * @var \Magento\Customer\Model\ResourceModel\GroupRepository */ @@ -154,6 +161,9 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + $this->model = new \Magento\Customer\Model\ResourceModel\GroupRepository( $this->groupRegistry, $this->groupFactory, @@ -162,7 +172,8 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase $this->dataObjectProcessor, $this->searchResultsFactory, $this->taxClassRepository, - $this->extensionAttributesJoinProcessor + $this->extensionAttributesJoinProcessor, + $this->collectionProcessorMock ); } @@ -346,10 +357,7 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase $groupId = 86; $groupExtension = $this->getMock('Magento\Customer\Api\Data\GroupExtensionInterface', [], [], '', false); - $filterGroup = $this->getMock('Magento\Framework\Api\Search\FilterGroup', [], [], '', false); - $filter = $this->getMock('Magento\Framework\Api\Filter', [], [], '', false); $collection = $this->getMock('Magento\Customer\Model\ResourceModel\Group\Collection', [], [], '', false); - $sortOrder = $this->getMock('Magento\Framework\Api\SortOrder', [], [], '', false); $searchCriteria = $this->getMockForAbstractClass( 'Magento\Framework\Api\SearchCriteriaInterface', [], @@ -380,48 +388,9 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase ->with($collection, 'Magento\Customer\Api\Data\GroupInterface'); $collection->expects($this->once()) ->method('addTaxClass'); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroup]); - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $filter->expects($this->once()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->once()) - ->method('getField') - ->willReturn('Field'); - $filter->expects($this->atLeastOnce()) - ->method('getValue') - ->willReturn('Value'); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->with(['Field'], [['eq' => 'Value']]); - $searchCriteria->expects($this->atLeastOnce()) - ->method('getSortOrders') - ->willReturn([$sortOrder]); - $sortOrder->expects($this->once()) - ->method('getField') - ->willReturn('Field'); - $collection->expects($this->once()) - ->method('addOrder') - ->with('Field', 'ASC'); - $sortOrder->expects($this->once()) - ->method('getDirection') - ->willReturn(\Magento\Framework\Api\SortOrder::SORT_ASC); - $searchCriteria->expects($this->once()) - ->method('getCurrentPage') - ->willReturn(1); - $collection->expects($this->once()) - ->method('setCurPage') - ->with(1); - $searchCriteria->expects($this->once()) - ->method('getPageSize') - ->willReturn(10); - $collection->expects($this->once()) - ->method('setPageSize') - ->with(10); + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $collection->expects($this->once()) ->method('getIterator') ->willReturn(new \ArrayIterator([$this->groupModel])); @@ -484,142 +453,6 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase $this->assertSame($searchResults, $this->model->getList($searchCriteria)); } - /** - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - */ - public function testGetListWithoutSortOrder() - { - $groupId = 86; - - $groupExtension = $this->getMock('Magento\Customer\Api\Data\GroupExtensionInterface', [], [], '', false); - $filterGroup = $this->getMock('Magento\Framework\Api\Search\FilterGroup', [], [], '', false); - $filter = $this->getMock('Magento\Framework\Api\Filter', [], [], '', false); - $collection = $this->getMock('Magento\Customer\Model\ResourceModel\Group\Collection', [], [], '', false); - $searchCriteria = $this->getMockForAbstractClass( - 'Magento\Framework\Api\SearchCriteriaInterface', - [], - '', - false - ); - $searchResults = $this->getMockForAbstractClass( - 'Magento\Customer\Api\Data\AddressSearchResultsInterface', - [], - '', - false - ); - $this->searchResultsFactory->expects($this->once()) - ->method('create') - ->willReturn($searchResults); - $searchResults->expects($this->once()) - ->method('setSearchCriteria') - ->with($searchCriteria); - - $this->groupFactory->expects($this->once()) - ->method('create') - ->willReturn($this->groupModel); - $this->groupModel->expects($this->once()) - ->method('getCollection') - ->willReturn($collection); - $this->extensionAttributesJoinProcessor->expects($this->once()) - ->method('process') - ->with($collection, 'Magento\Customer\Api\Data\GroupInterface'); - $collection->expects($this->once()) - ->method('addTaxClass'); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroup]); - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $filter->expects($this->once()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->once()) - ->method('getField') - ->willReturn('Field'); - $filter->expects($this->atLeastOnce()) - ->method('getValue') - ->willReturn('Value'); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->with(['Field'], [['eq' => 'Value']]); - - $searchCriteria->expects($this->once()) - ->method('getCurrentPage') - ->willReturn(1); - $collection->expects($this->once()) - ->method('setCurPage') - ->with(1); - $searchCriteria->expects($this->once()) - ->method('getPageSize') - ->willReturn(10); - $collection->expects($this->once()) - ->method('setPageSize') - ->with(10); - $collection->expects($this->once()) - ->method('getIterator') - ->willReturn(new \ArrayIterator([$this->groupModel])); - - $this->groupDataFactory->expects($this->once()) - ->method('create') - ->willReturn($this->group); - - $this->group->expects($this->once()) - ->method('setId') - ->with($groupId) - ->willReturnSelf(); - $this->group->expects($this->once()) - ->method('setCode') - ->with('Code') - ->willReturnSelf(); - $this->group->expects($this->once()) - ->method('setTaxClassId') - ->with(234) - ->willReturnSelf(); - $this->group->expects($this->once()) - ->method('setTaxClassName') - ->with('Tax class name') - ->willReturnSelf(); - - $this->groupModel->expects($this->atLeastOnce()) - ->method('getId') - ->willReturn($groupId); - $this->groupModel->expects($this->atLeastOnce()) - ->method('getCode') - ->willReturn('Code'); - $this->groupModel->expects($this->atLeastOnce()) - ->method('getTaxClassId') - ->willReturn(234); - $this->groupModel->expects($this->atLeastOnce()) - ->method('getTaxClassName') - ->willReturn('Tax class name'); - $this->groupModel->expects($this->once()) - ->method('getData') - ->willReturn([]); - $this->extensionAttributesJoinProcessor->expects($this->once()) - ->method('extractExtensionAttributes') - ->with('Magento\Customer\Api\Data\GroupInterface', []) - ->willReturn(['extension_attributes' => $groupExtension]); - $this->group->expects($this->once()) - ->method('setExtensionAttributes') - ->with($groupExtension); - $collection->expects($this->once()) - ->method('getSize') - ->willReturn(9); - $searchResults->expects($this->once()) - ->method('setTotalCount') - ->with(9); - $searchResults->expects($this->once()) - ->method('setItems') - ->with([$this->group]) - ->willReturnSelf(); - $collection->expects($this->once()) - ->method('addOrder') - ->with('customer_group_id', 'ASC'); - - $this->assertSame($searchResults, $this->model->getList($searchCriteria)); - } - public function testDeleteById() { $groupId = 6; diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index e47ee111e89..2ddf7426c91 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -320,6 +320,15 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> </arguments> </type> + <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="code" xsi:type="string">customer_group_code</item> + <item name="id" xsi:type="string">customer_group_id</item> + <item name="tax_class_name" xsi:type="string">class_name</item> + </argument> + </arguments> + </virtualType> <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\SortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> <arguments> <argument name="fieldMapping" xsi:type="array"> @@ -335,7 +344,7 @@ <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> <arguments> <argument name="processors" xsi:type="array"> - <item name="filters" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="filters" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> <item name="sorting" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> </argument> diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php index 2eaca95022d..63c71bd1bb1 100644 --- a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php @@ -54,6 +54,7 @@ class FilterProcessor implements CollectionProcessorInterface * * @param FilterGroup $filterGroup * @param AbstractDb $collection + * @return void */ private function addFilterGroupToCollection( FilterGroup $filterGroup, @@ -79,7 +80,6 @@ class FilterProcessor implements CollectionProcessorInterface } } - /** * Return custom filters for field if exists * diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php index 0cfac2a3adb..6b2f5705278 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/FilterProcessor.php @@ -54,6 +54,7 @@ class FilterProcessor implements CollectionProcessorInterface * * @param FilterGroup $filterGroup * @param AbstractDb $collection + * @return void */ private function addFilterGroupToCollection( FilterGroup $filterGroup, @@ -66,12 +67,12 @@ class FilterProcessor implements CollectionProcessorInterface $customFilter = $this->getCustomFilterForField($filter->getField()); if ($customFilter) { $isApplied = $customFilter->apply($filter, $collection); - } - + } + if (!$isApplied) { - $field = $this->getFieldMapping($filter->getField()); - $fields[$field] = $filter->getValue(); - $conditions[$field] = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; + $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; + $fields[] = $this->getFieldMapping($filter->getField()); + $conditions[] = [$condition => $filter->getValue()]; } } diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php index 29a9240073d..9e27ce9612a 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/SortingProcessor.php @@ -67,6 +67,7 @@ class SortingProcessor implements CollectionProcessorInterface * * @param SortOrder[] $sortOrders * @param AbstractDb $collection + * @return void */ private function applyOrders(array $sortOrders, AbstractDb $collection) { @@ -84,10 +85,12 @@ class SortingProcessor implements CollectionProcessorInterface * Apply default orders to collection * * @param AbstractDb $collection + * @return void */ private function applyDefaultOrders(AbstractDb $collection) { foreach ($this->defaultOrders as $field => $direction) { + $field = $this->getFieldMapping($field); $order = $direction == SortOrder::SORT_ASC ? Collection::SORT_ORDER_ASC : Collection::SORT_ORDER_DESC; diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php index 8fdd244f9b4..dd8ec1d0a29 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorInterface.php @@ -19,6 +19,7 @@ interface CollectionProcessorInterface * @param SearchCriteriaInterface $searchCriteria * @param AbstractDb $collection * @throws \InvalidArgumentException + * @return void */ public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection); } -- GitLab From f28303d82327cae954b6b866d6ec3a90a9968ac0 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Fri, 29 Jul 2016 12:25:07 +0300 Subject: [PATCH 079/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../Test/Unit/Model/ProductRepositoryTest.php | 16 +--------------- .../ResourceModel/CustomerRepositoryTest.php | 1 + 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php index f33b0935f2d..3cf35313c03 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php @@ -616,10 +616,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->model->deleteById($sku)); } - /** - * @dataProvider fieldName - */ - public function testGetList($fieldName) + public function testGetList() { $searchCriteriaMock = $this->getMock('\Magento\Framework\Api\SearchCriteriaInterface', [], [], '', false); $attributeCode = 'attribute_code'; @@ -1238,15 +1235,4 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase $this->model->save($this->productMock); $this->assertEquals($expectedResult, $this->initializedProductMock->getMediaGallery('images')); } - - /** - * @return array - */ - public function fieldName() - { - return [ - ['category_id'], - ['field'] - ]; - } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php index 9104d0a7359..ba25ca5fde3 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php @@ -11,6 +11,7 @@ use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase { -- GitLab From 4876f2242d8df00ce4e81b61c6bd1f0b58d71c1e Mon Sep 17 00:00:00 2001 From: Rafael Kassner <kassner@gmail.com> Date: Fri, 29 Jul 2016 11:41:22 +0200 Subject: [PATCH 080/838] Use alias already defined in requirejs-config.js Use alias already defined in requirejs-config.js so it can be overwritten/extended --- .../Catalog/view/frontend/templates/product/view/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index f6dd2a0033f..7de546bd878 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -40,7 +40,7 @@ <script> require([ 'jquery', - 'Magento_Catalog/js/price-box' + 'priceBox' ], function($){ var priceBoxes = $('[data-role=priceBox]'); -- GitLab From 67e86a1ec69f0731b6109a051af625307f933677 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Fri, 29 Jul 2016 15:17:19 +0300 Subject: [PATCH 081/838] MAGETWO-56008: Moving getStoreByWebsite to Store Module --- app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php | 3 +-- .../Store/Model/ResourceModel/StoreWebsiteRelation.php | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php b/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php index bcb9293c762..5b10eff928e 100644 --- a/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php +++ b/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php @@ -13,8 +13,7 @@ interface StoreWebsiteRelationInterface { /** * Get assigned to website store - * - * @param $websiteId + * @param int $websiteId * @return array */ public function getStoreByWebsiteId($websiteId); diff --git a/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php b/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php index 2ad62dfb172..a325ade4ccd 100644 --- a/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php +++ b/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ namespace Magento\Store\Model\ResourceModel; + use Magento\Framework\App\ResourceConnection; /** @@ -18,9 +19,7 @@ class StoreWebsiteRelation * StoreWebsiteRelation constructor. * @param ResourceConnection $resource */ - public function __construct( - ResourceConnection $resource - ) { + public function __construct(ResourceConnection $resource) { $this->resource = $resource; } -- GitLab From a7d582d3d35e7309a52e90c606fb101f06e90237 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 29 Jul 2016 17:02:16 +0300 Subject: [PATCH 082/838] MAGETWO-53549: [Github][PR] Replace fabpot/php-cs-fixer with friendsofphp/php-cs-fixer #4791 --- composer.lock | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/composer.lock b/composer.lock index 77553a16419..3c09ae6ccba 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "ad3de2234f78fd4b353ae6a1b22401fc", - "content-hash": "25dcf96ed1d8b12a25111e8b3af61317", + "hash": "9341127dac76c707c7e20a605b0a194e", + "content-hash": "d85d123648d39c22dc02674569b8aaee", "packages": [ { "name": "braintree/braintree_php", @@ -3232,17 +3232,17 @@ "time": "2015-06-14 21:17:01" }, { - "name": "fabpot/php-cs-fixer", - "version": "v1.11.5", + "name": "friendsofphp/php-cs-fixer", + "version": "v1.11.6", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "d3d08b76753092a232a4d8c3b94095ac06898719" + "reference": "41dc93abd2937a85a3889e28765231d574d2bac8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d3d08b76753092a232a4d8c3b94095ac06898719", - "reference": "d3d08b76753092a232a4d8c3b94095ac06898719", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/41dc93abd2937a85a3889e28765231d574d2bac8", + "reference": "41dc93abd2937a85a3889e28765231d574d2bac8", "shasum": "" }, "require": { @@ -3287,8 +3287,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "abandoned": "friendsofphp/php-cs-fixer", - "time": "2016-07-06 22:49:35" + "time": "2016-07-22 06:46:28" }, { "name": "lusitanian/oauth", -- GitLab From 51bc8658e45658d74b1f42ffdd10631c6cfb05e1 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Fri, 29 Jul 2016 17:35:28 +0300 Subject: [PATCH 083/838] MAGETWO-55364: [WCAG 2.0 AA] Add Aria-Labels for Color Swatches --- .../templates/product/layered/renderer.phtml | 11 +- .../view/frontend/web/css/swatches.css | 10 ++ .../view/frontend/web/js/swatch-renderer.js | 114 ++++++++++++++---- 3 files changed, 108 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml b/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml index 19b4002efb2..c8842b5b5be 100644 --- a/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml +++ b/app/code/Magento/Swatches/view/frontend/templates/product/layered/renderer.phtml @@ -10,15 +10,19 @@ ?> <?php $swatchData = $block->getSwatchData(); ?> <div class="swatch-attribute swatch-layered <?php /* @escapeNotVerified */ echo $swatchData['attribute_code'] ?>" - attribute-code="<?php /* @escapeNotVerified */ echo $swatchData['attribute_code'] ?>" attribute-id="<?php /* @escapeNotVerified */ echo $swatchData['attribute_id'] ?>"> + attribute-code="<?php /* @escapeNotVerified */ echo $swatchData['attribute_code'] ?>" + attribute-id="<?php /* @escapeNotVerified */ echo $swatchData['attribute_id'] ?>"> <div class="swatch-attribute-options clearfix"> <?php foreach ($swatchData['options'] as $option => $label): ?> - <a href="<?php /* @escapeNotVerified */ echo $label['link'] ?>" class="swatch-option-link-layered"> + <a href="<?php /* @escapeNotVerified */ echo $label['link'] ?>" + aria-label="<?php /* @escapeNotVerified */ echo $label['label'] ?>" + class="swatch-option-link-layered"> <?php if (isset($swatchData['swatches'][$option]['type'])) { ?> <?php switch ($swatchData['swatches'][$option]['type']) { case '3': ?> <div class="swatch-option <?php /* @escapeNotVerified */ echo $label['custom_style'] ?>" + tabindex="-1" option-type="3" option-id="<?php /* @escapeNotVerified */ echo $option ?>" option-label="<?php /* @escapeNotVerified */ echo $label['label'] ?>" @@ -33,6 +37,7 @@ <?php $swatchImagePath = $block->getSwatchPath('swatch_image', $swatchData['swatches'][$option]['value']); ?> <div class="swatch-option image <?php /* @escapeNotVerified */ echo $label['custom_style'] ?>" + tabindex="-1" option-type="2" option-id="<?php /* @escapeNotVerified */ echo $option ?>" option-label="<?php /* @escapeNotVerified */ echo $label['label'] ?>" @@ -43,6 +48,7 @@ case '1': ?> <div class="swatch-option color <?php /* @escapeNotVerified */ echo $label['custom_style'] ?>" + tabindex="-1" option-type="1" option-id="<?php /* @escapeNotVerified */ echo $option ?>" option-label="<?php /* @escapeNotVerified */ echo $label['label'] ?>" @@ -54,6 +60,7 @@ default: ?> <div class="swatch-option text <?php /* @escapeNotVerified */ echo $label['custom_style'] ?>" + tabindex="-1" option-type="0" option-id="<?php /* @escapeNotVerified */ echo $option ?>" option-label="<?php /* @escapeNotVerified */ echo $label['label'] ?>" diff --git a/app/code/Magento/Swatches/view/frontend/web/css/swatches.css b/app/code/Magento/Swatches/view/frontend/web/css/swatches.css index 8204fc7fc8f..3899a663788 100644 --- a/app/code/Magento/Swatches/view/frontend/web/css/swatches.css +++ b/app/code/Magento/Swatches/view/frontend/web/css/swatches.css @@ -210,6 +210,10 @@ padding: 0 !important; } +.swatch-option-link-layered:focus > div { + box-shadow: 0 0 3px 1px #68a8e0; +} + .swatch-option-tooltip-layered { width: 140px; position: absolute; @@ -276,3 +280,9 @@ .swatch-option-loading { content: url("../images/loader-2.gif"); } + +.swatch-input { + left: -1000px; + position: absolute; + visibility: hidden; +} diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index dfd4b2bb2da..93c84c5a301 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -117,6 +117,7 @@ define([ $element.hide(); clearTimeout(timer); }); + $(document).on('tap', function () { $element.hide(); clearTimeout(timer); @@ -169,6 +170,9 @@ define([ //selector of product images gallery wrapper mediaGallerySelector: '[data-gallery-role=gallery-placeholder]', + // selector of category product tile wrapper + selectorProductTile: '.product-item', + // number of controls to show (false or zero = show all) numberToShow: false, @@ -178,6 +182,9 @@ define([ // enable label for control enableControlLabel: true, + // control label id + controlLabelId: '', + // text for more button moreButtonText: 'More', @@ -191,7 +198,10 @@ define([ mediaGalleryInitial: [{}], // - onlyMainImg: false + onlyMainImg: false, + + // whether swatches are rendered in product list or on product page + inProductList: false }, /** @@ -246,7 +256,9 @@ define([ 'img': $main.find('.product-image-photo').attr('src') }]; } - this.productForm = this.element.parents(this.options.selectorProduct).find('form:first'); + + this.productForm = this.element.parents(this.options.selectorProductTile).find('form:first'); + this.inProductList = this.productForm.length > 0; }, /** @@ -264,9 +276,11 @@ define([ $.each(this.options.jsonConfig.attributes, function () { var item = this, - options = $widget._RenderSwatchOptions(item), + controlLabelId = 'option-label-' + item.code + '-' + item.id, + options = $widget._RenderSwatchOptions(item, controlLabelId), select = $widget._RenderSwatchSelect(item, chooseText), input = $widget._RenderFormInput(item), + listLabel ='', label = ''; // Show only swatch controls @@ -276,22 +290,28 @@ define([ if ($widget.options.enableControlLabel) { label += - '<span class="' + classes.attributeLabelClass + '">' + item.label + '</span>' + + '<span id="' + controlLabelId + '" class="' + classes.attributeLabelClass + '">' + item.label + '</span>' + '<span class="' + classes.attributeSelectedOptionLabelClass + '"></span>'; } - if ($widget.productForm) { + if ($widget.inProductList) { $widget.productForm.append(input); input = ''; + listLabel = 'aria-label="' + item.label + '"'; + } else { + listLabel = 'aria-labelledby="' + controlLabelId + '"'; } // Create new control container.append( - '<div class="' + classes.attributeClass + ' ' + item.code + - '" attribute-code="' + item.code + - '" attribute-id="' + item.id + '">' + - label + - '<div class="' + classes.attributeOptionsWrapper + ' clearfix">' + + '<div class="' + classes.attributeClass + ' ' + item.code + '" ' + + 'attribute-code="' + item.code + '" ' + + 'attribute-id="' + item.id + '">' + + label + + '<div aria-activedescendant="" ' + + 'tabindex="0" ' + + 'role="listbox" ' + listLabel + + 'class="' + classes.attributeOptionsWrapper + ' clearfix">' + options + select + '</div>' + input + '</div>' @@ -336,10 +356,11 @@ define([ * Render swatch options by part of config * * @param {Object} config + * @param {String} controlId * @returns {String} * @private */ - _RenderSwatchOptions: function (config) { + _RenderSwatchOptions: function (config, controlId) { var optionConfig = this.options.jsonSwatchConfig[config.id], optionClass = this.options.classes.optionClass, moreLimit = parseInt(this.options.numberToShow, 10), @@ -375,11 +396,17 @@ define([ thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : ''; label = this.label ? this.label : ''; attr = + ' id="' + controlId + '-item-' + id + '"' + + ' aria-checked="false"' + + ' aria-describedby="' + controlId + '"' + + ' tabindex="0"' + ' option-type="' + type + '"' + ' option-id="' + id + '"' + ' option-label="' + label + '"' + + ' aria-label="' + label + '"' + ' option-tooltip-thumb="' + thumb + '"' + - ' option-tooltip-value="' + value + '"'; + ' option-tooltip-value="' + value + '"' + + ' role="option"'; if (!this.hasOwnProperty('products') || this.products.length <= 0) { attr += ' option-empty="true"'; @@ -392,19 +419,19 @@ define([ } else if (type === 1) { // Color html += '<div class="' + optionClass + ' color" ' + attr + - '" style="background: ' + value + + ' style="background: ' + value + ' no-repeat center; background-size: initial;">' + '' + '</div>'; } else if (type === 2) { // Image html += '<div class="' + optionClass + ' image" ' + attr + - '" style="background: url(' + value + ') no-repeat center; background-size: initial;">' + '' + + ' style="background: url(' + value + ') no-repeat center; background-size: initial;">' + '' + '</div>'; } else if (type === 3) { // Clear html += '<div class="' + optionClass + '" ' + attr + '></div>'; } else { - // Defaualt + // Default html += '<div class="' + optionClass + '" ' + attr + '>' + label + '</div>'; } }); @@ -460,10 +487,9 @@ define([ 'type="text" ' + 'value="" ' + 'data-selector="super_attribute[' + config.id + ']" ' + - 'data-validate="{required:true}" ' + + 'data-validate="{required: true}" ' + 'aria-required="true" ' + - 'aria-invalid="true" ' + - 'style="visibility: hidden; position:absolute; left:-1000px">'; + 'aria-invalid="false">'; }, /** @@ -472,22 +498,38 @@ define([ * @private */ _EventListener: function () { + var $widget = this, + options = this.options.classes; - var $widget = this; - - $widget.element.on('click', '.' + this.options.classes.optionClass, function () { + $widget.element.on('click', '.' + options.optionClass, function () { return $widget._OnClick($(this), $widget); }); - $widget.element.on('change', '.' + this.options.classes.selectClass, function () { + $widget.element.on('change', '.' + options.selectClass, function () { return $widget._OnChange($(this), $widget); }); - $widget.element.on('click', '.' + this.options.classes.moreButton, function (e) { + $widget.element.on('click', '.' + options.moreButton, function (e) { e.preventDefault(); return $widget._OnMoreClick($(this)); }); + + $widget.element.on('keydown', function (e) { + if (e.which == 13) { + var target = $(e.target); + + if (target.is('.' + options.optionClass)) { + return $widget._OnClick(target, $widget); + } else if (target.is('.' + options.selectClass)) { + return $widget._OnChange(target, $widget); + } else if (target.is('.' + options.moreButton)) { + e.preventDefault(); + + return $widget._OnMoreClick(target); + } + } + }); }, /** @@ -498,13 +540,17 @@ define([ * @private */ _OnClick: function ($this, $widget) { - var $parent = $this.parents('.' + $widget.options.classes.attributeClass), + $wrapper = $this.parents('.' + $widget.options.classes.attributeOptionsWrapper), $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass), attributeId = $parent.attr('attribute-id'), + $input = $parent.find('.' + $widget.options.classes.attributeInput); + + if ($widget.inProductList) { $input = $widget.productForm.find( '.' + $widget.options.classes.attributeInput + '[name="super_attribute[' + attributeId + ']"]' ); + } if ($this.hasClass('disabled')) { return; @@ -514,11 +560,13 @@ define([ $parent.removeAttr('option-selected').find('.selected').removeClass('selected'); $input.val(''); $label.text(''); + $this.attr('aria-checked', false); } else { $parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected'); $label.text($this.attr('option-label')); $input.val($this.attr('option-id')); $this.addClass('selected'); + $widget._toggleCheckedAttributes($this, $wrapper); } $widget._Rebuild(); @@ -533,6 +581,19 @@ define([ $input.trigger('change'); }, + /** + * Toggle accessibility attributes + * + * @param {Object} $this + * @param {Object} $wrapper + * @private + */ + _toggleCheckedAttributes: function ($this, $wrapper) { + $wrapper.attr('aria-activedescendant', $this.attr('id')) + .find('.' + this.options.classes.optionClass).attr('aria-checked', false); + $this.attr('aria-checked', true); + }, + /** * Event for select * @@ -543,9 +604,13 @@ define([ _OnChange: function ($this, $widget) { var $parent = $this.parents('.' + $widget.options.classes.attributeClass), attributeId = $parent.attr('attribute-id'), + $input = $parent.find('.' + $widget.options.classes.attributeInput); + + if ($widget.productForm.length > 0) { $input = $widget.productForm.find( '.' + $widget.options.classes.attributeInput + '[name="super_attribute[' + attributeId + ']"]' ); + } if ($this.val() > 0) { $parent.attr('option-selected', $this.val()); @@ -687,7 +752,6 @@ define([ 'prices': $widget._getPrices(result, $productPrice.priceBox('option').prices) } ); - }, /** -- GitLab From ecf88c1f0d0471528a8e870054532edae524c041 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Fri, 29 Jul 2016 19:21:07 +0300 Subject: [PATCH 084/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../FilterProcessor/CategoryFilterTest.php | 73 +++++++ .../FilterProcessorTest.php | 197 +++++++++++++++++ .../Customer/Api/GroupRepositoryTest.php | 62 +++++- .../CollectionProcessorComposite.php | 4 +- .../FilterProcessorTest.php | 201 ++++++++++++++++++ .../PaginationProcessorTest.php | 43 ++++ .../SortingProcessorTest.php | 148 +++++++++++++ .../CollectionProcessorCompositeTest.php | 95 +++++++++ 8 files changed, 819 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php create mode 100644 app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php create mode 100644 lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php create mode 100644 lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/PaginationProcessorTest.php create mode 100644 lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php create mode 100644 lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php new file mode 100644 index 00000000000..2b9df60ed28 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CategoryFilter; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Framework\Api\Filter; + +class CategoryFilterTest extends \PHPUnit_Framework_TestCase +{ + /** @var CategoryFilter */ + private $model; + + protected function setUp() + { + $this->model = new CategoryFilter(); + } + + public function testApply() + { + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterMock */ + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collectionMock */ + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + + $filterMock->expects($this->exactly(2)) + ->method('getConditionType') + ->willReturn('condition'); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn('value'); + + $collectionMock->expects($this->once()) + ->method('addCategoriesFilter') + ->with(['condition' => ['value']]); + + $this->assertTrue($this->model->apply($filterMock, $collectionMock)); + } + + public function testApplyWithoutCondition() + { + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterMock */ + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collectionMock */ + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + + $filterMock->expects($this->once()) + ->method('getConditionType') + ->willReturn(null); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn('value'); + + $collectionMock->expects($this->once()) + ->method('addCategoriesFilter') + ->with(['eq' => ['value']]); + + $this->assertTrue($this->model->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php new file mode 100644 index 00000000000..4411f3b1574 --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php @@ -0,0 +1,197 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor; + +use Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class FilterProcessorTest extends \PHPUnit_Framework_TestCase +{ + /** + * Return model + * + * @param CustomFilterInterface[] $customFilters + * @param array $fieldMapping + * @return FilterProcessor + */ + private function getModel(array $customFilters, array $fieldMapping) + { + return new FilterProcessor($customFilters, $fieldMapping); + } + + public function testProcess() + { + /** @var CustomFilterInterface|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ + $customFilterMock = $this->getMockBuilder(CustomFilterInterface::class) + ->getMock(); + + $customFilterField = 'customFilterField'; + $customFilters = [$customFilterField => $customFilterMock]; + + $otherFilterField = 'otherFilterField'; + $otherFilterFieldMapped = 'otherFilterFieldMapped'; + $fieldMapping = [$otherFilterField => $otherFilterFieldMapped]; + $otherFilterFieldValue = 'otherFilterFieldValue'; + $otherFilterFieldCondition = 'gt'; + + $thirdField = 'thirdField'; + $thirdFieldValue = 'thirdFieldValue'; + $thirdFieldCondition = ''; + + $resultOne = [ + [ + 'attribute' => $otherFilterFieldMapped, + $otherFilterFieldCondition => $otherFilterFieldValue, + ], + ]; + $resultTwo = [ + [ + 'attribute' => $thirdField, + 'eq' => $thirdFieldValue, + ], + ]; + + $model = $this->getModel($customFilters, $fieldMapping); + + /** @var FilterGroup|\PHPUnit_Framework_MockObject_MockObject $filterGroupOneMock */ + $filterGroupOneMock = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var FilterGroup|\PHPUnit_Framework_MockObject_MockObject $filterGroupTwoMock */ + $filterGroupTwoMock = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterOneMock */ + $filterOneMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterOneMock->expects($this->once()) + ->method('getField') + ->willReturn($customFilterField); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterTwoMock */ + $filterTwoMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterTwoMock->expects($this->exactly(2)) + ->method('getField') + ->willReturn($otherFilterField); + $filterTwoMock->expects($this->once()) + ->method('getValue') + ->willReturn($otherFilterFieldValue); + $filterTwoMock->expects($this->exactly(2)) + ->method('getConditionType') + ->willReturn($otherFilterFieldCondition); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterThreeMock */ + $filterThreeMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterThreeMock->expects($this->exactly(2)) + ->method('getField') + ->willReturn($thirdField); + $filterThreeMock->expects($this->once()) + ->method('getValue') + ->willReturn($thirdFieldValue); + $filterThreeMock->expects($this->once()) + ->method('getConditionType') + ->willReturn($thirdFieldCondition); + + $filterGroupOneMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterOneMock, $filterTwoMock]); + + $filterGroupTwoMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterThreeMock]); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $searchCriteriaMock->expects($this->once()) + ->method('getFilterGroups') + ->willReturn([$filterGroupOneMock, $filterGroupTwoMock]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $customFilterMock->expects($this->once()) + ->method('apply') + ->with($filterOneMock, $collectionMock) + ->willReturn(true); + + $collectionMock->expects($this->exactly(2)) + ->method('addFieldToFilter') + ->withConsecutive( + [$resultOne], + [$resultTwo] + )->willReturnSelf(); + + $model->process($searchCriteriaMock, $collectionMock); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testProcessWithException() + { + /** @var \stdClass|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ + $customFilterMock = $this->getMockBuilder(\stdClass::class) + ->getMock(); + + $customFilterField = 'customFilterField'; + $customFilters = [$customFilterField => $customFilterMock]; + + $model = $this->getModel($customFilters, []); + + /** @var FilterGroup|\PHPUnit_Framework_MockObject_MockObject $filterGroupOneMock */ + $filterGroupOneMock = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterOneMock */ + $filterOneMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterOneMock->expects($this->once()) + ->method('getField') + ->willReturn($customFilterField); + + $filterGroupOneMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterOneMock]); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $searchCriteriaMock->expects($this->once()) + ->method('getFilterGroups') + ->willReturn([$filterGroupOneMock]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $customFilterMock->expects($this->never()) + ->method('apply'); + + $collectionMock->expects($this->never()) + ->method('addFieldToFilter'); + + $model->process($searchCriteriaMock, $collectionMock); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php index 343e69bcc07..47315df6937 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php @@ -6,9 +6,14 @@ namespace Magento\Customer\Api; +use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Model\Data\Group as CustomerGroup; use Magento\Customer\Model\GroupRegistry; use Magento\Customer\Model\ResourceModel\GroupRepository; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -923,7 +928,7 @@ class GroupRepositoryTest extends WebapiAbstract public function testSearchGroups($filterField, $filterValue, $expectedResult) { $filterBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder'); - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */ + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ $searchCriteriaBuilder = Bootstrap::getObjectManager() ->create('Magento\Framework\Api\SearchCriteriaBuilder'); $filter = $filterBuilder @@ -958,6 +963,59 @@ class GroupRepositoryTest extends WebapiAbstract } } + public function testSearchGroupsWithMultipleFilterGroupsAndSorting() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(GroupInterface::CODE) + ->setValue('General') + ->create(); + $filter2 = $filterBuilder->setField(GroupInterface::CODE) + ->setValue('Retailer') + ->create(); + $filter3 = $filterBuilder->setField(GroupInterface::CODE) + ->setValue('Wholesale') + ->create(); + $filter4 = $filterBuilder->setField(GroupInterface::ID) + ->setValue(1) + ->setConditionType('gt') + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(GroupInterface::CODE)->setDirection(SortOrder::SORT_ASC)->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3]); + $searchCriteriaBuilder->addFilters([$filter4]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchData = $searchCriteriaBuilder->create()->__toArray(); + $requestData = ['searchCriteria' => $searchData]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . "/search" . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => 'customerGroupRepositoryV1GetList', + ], + ]; + + $searchResult = $this->_webApiCall($serviceInfo, $requestData); + + $this->assertEquals(2, $searchResult['total_count']); + $this->assertEquals(3, $searchResult['items'][0][GroupInterface::ID]); + $this->assertEquals(2, $searchResult['items'][1][GroupInterface::ID]); + } + /** * Test search customer group using GET * @@ -971,7 +1029,7 @@ class GroupRepositoryTest extends WebapiAbstract { $this->_markTestAsRestOnly('SOAP is covered in '); $filterBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder'); - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */ + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ $searchCriteriaBuilder = Bootstrap::getObjectManager() ->create('Magento\Framework\Api\SearchCriteriaBuilder'); $filter = $filterBuilder diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php index acc6b802fb2..d4f0229877e 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php @@ -29,10 +29,10 @@ class CollectionProcessorComposite implements CollectionProcessorInterface */ public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) { - foreach ($this->processors as $processor) { + foreach ($this->processors as $name => $processor) { if (!($processor instanceof CollectionProcessorInterface)) { throw new \InvalidArgumentException( - sprintf('Processor must implement %s interface.', CollectionProcessorInterface::class) + sprintf('Processor %s must implement %s interface.', $name, CollectionProcessorInterface::class) ); } $processor->process($searchCriteria, $collection); diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php new file mode 100644 index 00000000000..bd149cbc559 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php @@ -0,0 +1,201 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\Test\Unit\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class FilterProcessorTest extends \PHPUnit_Framework_TestCase +{ + /** + * Return model + * + * @param CustomFilterInterface[] $customFilters + * @param array $fieldMapping + * @return FilterProcessor + */ + private function getModel(array $customFilters, array $fieldMapping) + { + return new FilterProcessor($customFilters, $fieldMapping); + } + + public function testProcess() + { + /** @var CustomFilterInterface|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ + $customFilterMock = $this->getMockBuilder(CustomFilterInterface::class) + ->getMock(); + + $customFilterField = 'customFilterField'; + $customFilters = [$customFilterField => $customFilterMock]; + + $otherFilterField = 'otherFilterField'; + $otherFilterFieldMapped = 'otherFilterFieldMapped'; + $fieldMapping = [$otherFilterField => $otherFilterFieldMapped]; + $otherFilterFieldValue = 'otherFilterFieldValue'; + $otherFilterFieldCondition = 'gt'; + + $thirdField = 'thirdField'; + $thirdFieldValue = 'thirdFieldValue'; + $thirdFieldCondition = ''; + + $resultFieldsOne = [ + $otherFilterFieldMapped, + ]; + $resultConditionsOne = [ + [ + $otherFilterFieldCondition => $otherFilterFieldValue, + ], + ]; + $resultFieldsTwo = [ + $thirdField, + ]; + $resultConditionsTwo = [ + [ + 'eq' => $thirdFieldValue, + ], + ]; + + $model = $this->getModel($customFilters, $fieldMapping); + + /** @var FilterGroup|\PHPUnit_Framework_MockObject_MockObject $filterGroupOneMock */ + $filterGroupOneMock = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var FilterGroup|\PHPUnit_Framework_MockObject_MockObject $filterGroupTwoMock */ + $filterGroupTwoMock = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterOneMock */ + $filterOneMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterOneMock->expects($this->once()) + ->method('getField') + ->willReturn($customFilterField); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterTwoMock */ + $filterTwoMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterTwoMock->expects($this->exactly(2)) + ->method('getField') + ->willReturn($otherFilterField); + $filterTwoMock->expects($this->once()) + ->method('getValue') + ->willReturn($otherFilterFieldValue); + $filterTwoMock->expects($this->exactly(2)) + ->method('getConditionType') + ->willReturn($otherFilterFieldCondition); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterThreeMock */ + $filterThreeMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterThreeMock->expects($this->exactly(2)) + ->method('getField') + ->willReturn($thirdField); + $filterThreeMock->expects($this->once()) + ->method('getValue') + ->willReturn($thirdFieldValue); + $filterThreeMock->expects($this->once()) + ->method('getConditionType') + ->willReturn($thirdFieldCondition); + + $filterGroupOneMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterOneMock, $filterTwoMock]); + + $filterGroupTwoMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterThreeMock]); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $searchCriteriaMock->expects($this->once()) + ->method('getFilterGroups') + ->willReturn([$filterGroupOneMock, $filterGroupTwoMock]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $customFilterMock->expects($this->once()) + ->method('apply') + ->with($filterOneMock, $collectionMock) + ->willReturn(true); + + $collectionMock->expects($this->exactly(2)) + ->method('addFieldToFilter') + ->withConsecutive( + [$resultFieldsOne, $resultConditionsOne], + [$resultFieldsTwo, $resultConditionsTwo] + )->willReturnSelf(); + + $model->process($searchCriteriaMock, $collectionMock); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testProcessWithException() + { + /** @var \stdClass|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ + $customFilterMock = $this->getMockBuilder(\stdClass::class) + ->getMock(); + + $customFilterField = 'customFilterField'; + $customFilters = [$customFilterField => $customFilterMock]; + + $model = $this->getModel($customFilters, []); + + /** @var FilterGroup|\PHPUnit_Framework_MockObject_MockObject $filterGroupOneMock */ + $filterGroupOneMock = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Filter|\PHPUnit_Framework_MockObject_MockObject $filterOneMock */ + $filterOneMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterOneMock->expects($this->once()) + ->method('getField') + ->willReturn($customFilterField); + + $filterGroupOneMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterOneMock]); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $searchCriteriaMock->expects($this->once()) + ->method('getFilterGroups') + ->willReturn([$filterGroupOneMock]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $customFilterMock->expects($this->never()) + ->method('apply'); + + $collectionMock->expects($this->never()) + ->method('addFieldToFilter'); + + $model->process($searchCriteriaMock, $collectionMock); + } +} diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/PaginationProcessorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/PaginationProcessorTest.php new file mode 100644 index 00000000000..57b2ccf3382 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/PaginationProcessorTest.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\Test\Unit\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class PaginationProcessorTest extends \PHPUnit_Framework_TestCase +{ + public function testProcess() + { + $model = new PaginationProcessor; + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + $searchCriteriaMock->expects($this->once()) + ->method('getCurrentPage') + ->willReturn(22); + $searchCriteriaMock->expects($this->once()) + ->method('getPageSize') + ->willReturn(33); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + $collectionMock->expects($this->once()) + ->method('setCurPage') + ->with(22) + ->willReturnSelf(); + $collectionMock->expects($this->once()) + ->method('setPageSize') + ->with(33) + ->willReturnSelf(); + + $model->process($searchCriteriaMock, $collectionMock); + } +} diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php new file mode 100644 index 00000000000..6aec2fae94e --- /dev/null +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php @@ -0,0 +1,148 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\Test\Unit\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Data\Collection; +use Magento\Framework\Data\Collection\AbstractDb; + +class SortingProcessorTest extends \PHPUnit_Framework_TestCase +{ + /** + * Return model + * + * @param array $fieldMapping + * @param array $defaultOrders + * @return SortingProcessor + */ + private function getModel( array $fieldMapping, array $defaultOrders) + { + return new SortingProcessor($fieldMapping, $defaultOrders); + } + + public function testProcess() + { + $orderOneField = 'orderOneField'; + $orderOneFieldMapped = 'orderOneFieldMapped'; + $orderOneDirection = SortOrder::SORT_ASC; + + $orderTwoField = 'orderTwoField'; + $orderTwoDirection = SortOrder::SORT_DESC; + + $orderThreeField = 'orderTwoField'; + $orderThreeDirection = '!!@!@'; + + $fieldMapping = [$orderOneField => $orderOneFieldMapped]; + + $defaultOrders = ['orderTwoField' => 'DESC']; + + $model = $this->getModel($fieldMapping, $defaultOrders); + + /** @var SortOrder|\PHPUnit_Framework_MockObject_MockObject $sortOrderOneMock */ + $sortOrderOneMock = $this->getMockBuilder(SortOrder::class) + ->disableOriginalConstructor() + ->getMock(); + $sortOrderOneMock->expects($this->once()) + ->method('getField') + ->willReturn($orderOneField); + $sortOrderOneMock->expects($this->once()) + ->method('getDirection') + ->willReturn($orderOneDirection); + + /** @var SortOrder|\PHPUnit_Framework_MockObject_MockObject $sortOrderTwoMock */ + $sortOrderTwoMock = $this->getMockBuilder(SortOrder::class) + ->disableOriginalConstructor() + ->getMock(); + $sortOrderTwoMock->expects($this->once()) + ->method('getField') + ->willReturn($orderTwoField); + $sortOrderTwoMock->expects($this->once()) + ->method('getDirection') + ->willReturn($orderTwoDirection); + + /** @var SortOrder|\PHPUnit_Framework_MockObject_MockObject $sortOrderThreeMock */ + $sortOrderThreeMock = $this->getMockBuilder(SortOrder::class) + ->disableOriginalConstructor() + ->getMock(); + $sortOrderThreeMock->expects($this->once()) + ->method('getField') + ->willReturn($orderThreeField); + $sortOrderThreeMock->expects($this->once()) + ->method('getDirection') + ->willReturn($orderThreeDirection); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $searchCriteriaMock->expects($this->exactly(2)) + ->method('getSortOrders') + ->willReturn([$sortOrderOneMock, $sortOrderTwoMock, $sortOrderThreeMock]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $collectionMock->expects($this->exactly(3)) + ->method('addOrder') + ->withConsecutive( + [$orderOneFieldMapped, $orderOneDirection], + [$orderTwoField, $orderTwoDirection], + [$orderThreeField, Collection::SORT_ORDER_DESC] + )->willReturnSelf(); + + $model->process($searchCriteriaMock, $collectionMock); + } + + public function testProcessWithDefaults() + { + $defaultOneField = 'defaultOneField'; + $defaultOneFieldMapped = 'defaultOneFieldMapped'; + $defaultOneDirection = SortOrder::SORT_ASC; + + $defaultTwoField = 'defaultTwoField'; + $defaultTwoDirection = SortOrder::SORT_DESC; + + $defaultThreeField = 'defaultThreeField'; + $defaultThreeDirection = '$#%^'; + + $fieldMapping = [$defaultOneField => $defaultOneFieldMapped]; + + $defaultOrders = [ + $defaultOneField => $defaultOneDirection, + $defaultTwoField => $defaultTwoDirection, + $defaultThreeField => $defaultThreeDirection, + ]; + + $model = $this->getModel($fieldMapping, $defaultOrders); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $searchCriteriaMock->expects($this->once()) + ->method('getSortOrders') + ->willReturn([]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $collectionMock->expects($this->exactly(3)) + ->method('addOrder') + ->withConsecutive( + [$defaultOneFieldMapped, $defaultOneDirection], + [$defaultTwoField, $defaultTwoDirection], + [$defaultThreeField, Collection::SORT_ORDER_DESC] + )->willReturnSelf(); + + $model->process($searchCriteriaMock, $collectionMock); + } +} diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php new file mode 100644 index 00000000000..a19c9063e37 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\Test\Unit\SearchCriteria; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class CollectionProcessorCompositeTest extends \PHPUnit_Framework_TestCase +{ + /** + * Return model + * + * @param CollectionProcessorInterface[] $processors + * @return CollectionProcessorComposite + */ + private function getModel(array $processors) + { + return new CollectionProcessorComposite($processors); + } + + public function testProcess() + { + /** @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ + $processorOneMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + + /** @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject $processorTwoMock */ + $processorTwoMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + + $processors = [$processorOneMock, $processorTwoMock]; + + $model = $this->getModel($processors); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $processorOneMock->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); + + $processorTwoMock->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); + + $model->process($searchCriteriaMock, $collectionMock); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testProcessWithException() + { + /** @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ + $processorOneMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + + /** @var \stdClass|\PHPUnit_Framework_MockObject_MockObject $processorTwoMock */ + $processorTwoMock = $this->getMockBuilder(\stdClass::class) + ->getMock(); + + $processors = [$processorOneMock, $processorTwoMock]; + + $model = $this->getModel($processors); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $processorOneMock->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); + + $processorTwoMock->expects($this->never()) + ->method('process');; + + $model->process($searchCriteriaMock, $collectionMock); + } +} -- GitLab From 7a5304777a7579384d487878ab54ff77e76b7b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Paw=C5=82owski?= <mac@macu.eu> Date: Sun, 31 Jul 2016 20:28:11 +0200 Subject: [PATCH 085/838] Added missing translation to grid: range filter --- .../Magento/Ui/view/base/web/js/grid/filters/range.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js index b068af92aec..6af90fdf688 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/range.js @@ -6,8 +6,9 @@ define([ 'underscore', 'uiLayout', 'mageUtils', - 'Magento_Ui/js/form/components/group' -], function (_, layout, utils, Group) { + 'Magento_Ui/js/form/components/group', + 'mage/translate' +], function (_, layout, utils, Group, $t) { 'use strict'; return Group.extend({ @@ -29,11 +30,11 @@ define([ }, ranges: { from: { - label: 'from', + label: $t('from'), dataScope: 'from' }, to: { - label: 'to', + label: $t('to'), dataScope: 'to' } } -- GitLab From 70c44af93f808196d06b868894cc1616ebbf56b7 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Mon, 1 Aug 2016 11:16:07 +0300 Subject: [PATCH 086/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../SearchCriteria/CollectionProcessor/FilterProcessorTest.php | 3 +++ .../testsuite/Magento/Customer/Api/GroupRepositoryTest.php | 2 ++ .../SearchCriteria/CollectionProcessor/FilterProcessorTest.php | 3 +++ .../CollectionProcessor/SortingProcessorTest.php | 2 +- .../Unit/SearchCriteria/CollectionProcessorCompositeTest.php | 2 +- 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php index 4411f3b1574..06f618ab470 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessorTest.php @@ -26,6 +26,9 @@ class FilterProcessorTest extends \PHPUnit_Framework_TestCase return new FilterProcessor($customFilters, $fieldMapping); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testProcess() { /** @var CustomFilterInterface|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php index 47315df6937..fb316df8933 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php @@ -20,6 +20,8 @@ use Magento\TestFramework\TestCase\WebapiAbstract; /** * Class GroupRepositoryTest + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class GroupRepositoryTest extends WebapiAbstract { diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php index bd149cbc559..d15e34774b3 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/FilterProcessorTest.php @@ -26,6 +26,9 @@ class FilterProcessorTest extends \PHPUnit_Framework_TestCase return new FilterProcessor($customFilters, $fieldMapping); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testProcess() { /** @var CustomFilterInterface|\PHPUnit_Framework_MockObject_MockObject $customFilterMock */ diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php index 6aec2fae94e..68b4d6cee69 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/SortingProcessorTest.php @@ -20,7 +20,7 @@ class SortingProcessorTest extends \PHPUnit_Framework_TestCase * @param array $defaultOrders * @return SortingProcessor */ - private function getModel( array $fieldMapping, array $defaultOrders) + private function getModel(array $fieldMapping, array $defaultOrders) { return new SortingProcessor($fieldMapping, $defaultOrders); } diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php index a19c9063e37..5cbcb071664 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php @@ -88,7 +88,7 @@ class CollectionProcessorCompositeTest extends \PHPUnit_Framework_TestCase ->with($searchCriteriaMock, $collectionMock); $processorTwoMock->expects($this->never()) - ->method('process');; + ->method('process'); $model->process($searchCriteriaMock, $collectionMock); } -- GitLab From 8ed3eea4b66217f3751e67656b88417aa1eced71 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 1 Aug 2016 15:49:31 +0300 Subject: [PATCH 087/838] MAGETWO-53569: [Github] Import custom options type 'file' fails #4035 --- .../Magento/CatalogImportExport/Model/Export/Product.php | 8 ++++++++ .../CatalogImportExport/Model/Import/Product/Option.php | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 441fb60f55e..85d4c218fa4 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -1263,6 +1263,14 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity $row['max_characters'] = $option['max_characters']; } + foreach (['file_extension', 'image_size_x', 'image_size_y'] as $fileOptionKey) { + if (!isset($option[$fileOptionKey])) { + continue; + } + + $row[$fileOptionKey] = $option[$fileOptionKey]; + } + $values = $option->getValues(); if ($values) { diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index cb4a603f545..eaac35ac4f8 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -105,6 +105,7 @@ class Option extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity 'radio' => true, 'checkbox' => true, 'multiple' => true, + 'file' => ['sku', 'file_extension', 'image_size_x', 'image_size_y'], ]; /** @@ -1136,6 +1137,14 @@ class Option extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $result[$this->columnMaxCharacters] = $optionRow['max_characters']; } + foreach (['file_extension', 'image_size_x', 'image_size_y'] as $fileOptionKey) { + if (!isset($optionRow[$fileOptionKey])) { + continue; + } + + $result[self::COLUMN_PREFIX . $fileOptionKey] = $optionRow[$fileOptionKey]; + } + return $result; } -- GitLab From dcbc421b90a984ca8e3eeb570d43bba79262c7fd Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 1 Aug 2016 08:51:29 -0500 Subject: [PATCH 088/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../customer/edit/tab/wishlist.phtml | 8 +++---- .../frontend/templates/button/share.phtml | 4 ++-- .../frontend/templates/button/tocart.phtml | 4 ++-- .../frontend/templates/button/update.phtml | 4 ++-- .../renderer/actions/move_to_wishlist.phtml | 2 +- .../catalog/product/list/addto/wishlist.phtml | 2 +- .../catalog/product/view/addto/wishlist.phtml | 2 +- .../view/frontend/templates/email/items.phtml | 6 ++--- .../templates/item/column/actions.phtml | 6 ++--- .../frontend/templates/item/column/cart.phtml | 20 ++++++++-------- .../templates/item/column/comment.phtml | 7 +++--- .../frontend/templates/item/column/edit.phtml | 2 +- .../templates/item/column/price.phtml | 2 +- .../templates/item/column/remove.phtml | 6 +++-- .../templates/item/configure/addto.phtml | 6 +++-- .../item/configure/addto/wishlist.phtml | 2 +- .../view/frontend/templates/item/list.phtml | 4 ++-- .../view/frontend/templates/link.phtml | 2 +- .../messages/addProductSuccessMessage.phtml | 2 +- .../frontend/templates/options_list.phtml | 8 +++---- .../frontend/templates/rss/wishlist.phtml | 2 +- .../view/frontend/templates/shared.phtml | 24 +++++++++---------- .../view/frontend/templates/sharing.phtml | 22 ++++++++--------- .../view/frontend/templates/sidebar.phtml | 16 ++++++------- .../view/frontend/templates/view.phtml | 4 ++-- .../Framework/View/Element/Html/Link.php | 2 +- 26 files changed, 87 insertions(+), 82 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index f075b5a2c33..334401d8ec0 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -23,13 +23,13 @@ if (!urlParams) { urlParams = ''; } - var url = <?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>.url + '?ajax=true' + urlParams; + var url = <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; new Ajax.Updater( - <?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>.containerId, + <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.containerId, url, { parameters: {form_key: FORM_KEY}, - onComplete: <?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>.initGrid.bind(<?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>), + onComplete: <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeHtml($block->getJsObjectName()) ?>), evalScripts:true } ); @@ -52,7 +52,7 @@ var self = this; confirm({ - content: '<?php /* @escapeNotVerified */ echo __('Are you sure you want to remove this item?') ?>', + content: '<?php /* @noEscape */ echo __('Are you sure you want to remove this item?') ?>', actions: { confirm: function () { self.reload('&delete=' + itemId); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml index bace2114dab..558835f70d7 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml @@ -9,7 +9,7 @@ /** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->getShared() < $block->getConfig()->getSharingEmailLimit()): ?> - <button type="submit" name="save_and_share" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action share"> - <span><?php /* @escapeNotVerified */ echo __('Share Wish List') ?></span> + <button type="submit" name="save_and_share" title="<?php /* @noEscape */ echo __('Share Wish List') ?>" class="action share"> + <span><?php /* @noEscape */ echo __('Share Wish List') ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml index 3ae19be0339..b177b14f3a1 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml @@ -9,7 +9,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->isSalable()): ?> - <button type="button" data-role="all-tocart" title="<?php /* @escapeNotVerified */ echo __('Add All to Cart') ?>" class="action tocart"> - <span><?php /* @escapeNotVerified */ echo __('Add All to Cart') ?></span> + <button type="button" data-role="all-tocart" title="<?php /* @noEscape */ echo __('Add All to Cart') ?>" class="action tocart"> + <span><?php /* @noEscape */ echo __('Add All to Cart') ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml index 1d4125c486b..bc1fd87f9fa 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml @@ -9,7 +9,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount()): ?> - <button type="submit" name="do" title="<?php /* @escapeNotVerified */ echo __('Update Wish List') ?>" class="action update"> - <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> + <button type="submit" name="do" title="<?php /* @noEscape */ echo __('Update Wish List') ?>" class="action update"> + <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml index 5c3c6e63e09..e115b71ba84 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml @@ -12,6 +12,6 @@ <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getMoveFromCartParams(); ?>' class="use-ajax action action-towishlist"> - <span><?php /* @escapeNotVerified */ echo __('Move to Wishlist'); ?></span> + <span><?php /* @noEscape */ echo __('Move to Wishlist'); ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index 8e4f09645f1..a618788dfd8 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -15,6 +15,6 @@ data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' data-action="add-to-wishlist" role="button"> - <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> + <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml index eebd6070ad8..1062df9eb44 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml @@ -12,7 +12,7 @@ <a href="#" class="action towishlist" data-post='<?php /* @escapeNotVerified */ echo $block->getWishlistParams(); ?>' - data-action="add-to-wishlist"><span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span></a> + data-action="add-to-wishlist"><span><?php /* @noEscape */ echo __('Add to Wish List') ?></span></a> <?php endif; ?> <script type="text/x-magento-init"> { diff --git a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml index 8622a9ba50c..f5569316162 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml @@ -31,13 +31,13 @@ </p> <?php if ($block->hasDescription($item)): ?> <p> - <strong><?= /* @escapeNotVerified */ __('Comment') ?>:</strong> - <br/><?= /* @escapeNotVerified */ $block->getEscapedDescription($item) ?> + <strong><?= /* @noEscape */ __('Comment') ?>:</strong> + <br/><?= /* @noEscape */ $block->getEscapedDescription($item) ?> </p> <?php endif; ?> <p> <a href="<?= /* @escapeNotVerified */ $block->getProductUrl($_product) ?>"> - <?= /* @escapeNotVerified */ __('View Product') ?> + <?= /* @noEscape */ __('View Product') ?> </a> </p> </td> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index 2b92553811e..f03b5ec3a29 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -6,14 +6,14 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ /* @var \Magento\Wishlist\Model\Item $item */ ?> - <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> - <div class="<?php /* @escapeNotVerified */ echo $block->getCssClass() ?>"> + <div class="<?php echo $block->escapeHtml($block->getCssClass()) ?>"> <?php foreach ($children as $childName):?> - <?php /* @escapeNotVerified */ echo $block->getLayout()->renderElement($childName, false);?> + <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false);?> <?php endforeach;?> </div> <?php endif; ?> 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 d4af3e4e7a1..da6f4f86917 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 @@ -12,35 +12,35 @@ $item = $block->getItem(); $product = $item->getProduct(); ?> <?php foreach ($block->getChildNames() as $childName): ?> - <?php /* @escapeNotVerified */ echo $block->getLayout()->renderElement($childName, false); ?> + <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false); ?> <?php endforeach;?> <div class="box-tocart"> <fieldset class="fieldset"> <?php if ($item->canHaveQty() && $product->isVisibleInSiteVisibility()): ?> <div class="field qty"> - <label class="label" for="qty[<?php /* @escapeNotVerified */ echo $item->getId() ?>]"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label> + <label class="label" for="qty[<?php echo $block->escapeHtml($item->getId()) ?>]"><span><?php /* @noEscape */ echo __('Qty') ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?php /* @escapeNotVerified */ echo $item->getId() ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" - name="qty[<?php /* @escapeNotVerified */ echo $item->getId() ?>]" value="<?php /* @escapeNotVerified */ echo $block->getAddToCartQty($item) * 1 ?>"> + <input type="number" data-role="qty" id="qty[<?php echo $block->escapeHtml($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" + name="qty[<?php echo $block->escapeHtml($item->getId()) ?>]" value="<?php echo (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> <?php endif; ?> <?php if ($product->isSaleable()): ?> <div class="product-item-actions"> <div class="actions-primary"> - <button type="button" data-role="tocart" data-post='<?php /* @escapeNotVerified */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>" data-item-id="<?php /* @escapeNotVerified */ echo $item->getId()?>" class="action tocart primary"> - <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> + <button type="button" data-role="tocart" data-post='<?php /* @escapeNotVerified */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtml($item->getId())?>" class="action tocart primary"> + <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> </button> </div> </div> <?php else: ?> <?php if ($product->getIsSalable()): ?> - <p class="available stock" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>"> - <span><?php /* @escapeNotVerified */ echo __('In stock') ?></span> + <p class="available stock" title="<?php /* @noEscape */ echo __('Availability') ?>"> + <span><?php /* @noEscape */ echo __('In stock') ?></span> </p> <?php else: ?> - <p class="unavailable stock" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span> + <p class="unavailable stock" title="<?php /* @noEscape */ echo __('Availability') ?>"> + <span><?php /* @noEscape */ echo __('Out of stock') ?></span> </p> <?php endif; ?> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index f124a40b6f9..86d13cf7bf6 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -6,16 +6,17 @@ // @codingStandardsIgnoreFile +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ /* @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); ?> <div class="field comment-box"> - <label class="label" for="product-item-comment-<?php /* @escapeNotVerified */ echo $item->getWishlistItemId() ?>"> - <span><?php /* @escapeNotVerified */ echo __('Comment') ?></span> + <label class="label" for="product-item-comment-<?php echo $block->escapeHtml($item->getWishlistItemId()) ?>"> + <span><?php /* @noEscape */ echo __('Comment') ?></span> </label> <div class="control"> - <textarea id="product-item-comment-<?php /* @escapeNotVerified */ echo $item->getWishlistItemId() ?>" placeholder="<?php /* @escapeNotVerified */ echo $this->helper('Magento\Wishlist\Helper\Data')->defaultCommentString() ?>" name="description[<?php /* @escapeNotVerified */ echo $item->getWishlistItemId() ?>]" title="<?php /* @escapeNotVerified */ echo __('Comment') ?>" class="product-item-comment"><?php echo($block->escapeHtml($item->getDescription())) ?></textarea> + <textarea id="product-item-comment-<?php echo $block->escapeHtml($item->getWishlistItemId()) ?>" placeholder="<?php /* @noEscape */ echo $this->helper('Magento\Wishlist\Helper\Data')->defaultCommentString() ?>" name="description[<?php echo $block->escapeHtml($item->getWishlistItemId()) ?>]" title="<?php /* @noEscape */ echo __('Comment') ?>" class="product-item-comment"><?php echo($block->escapeHtml($item->getDescription())) ?></textarea> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index 7a8a1bd20c5..ac33424138a 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -13,6 +13,6 @@ $product = $item->getProduct(); <?php if ($product->isVisibleInSiteVisibility()): ?> <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getItemConfigureUrl($item) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Edit') ?></span> + <span><?php /* @noEscape */ echo __('Edit') ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml index 860fae9fa09..b12d3265fff 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml @@ -10,5 +10,5 @@ ?> <?php foreach ($block->getChildNames() as $childName): ?> - <?php /* @escapeNotVerified */ echo $block->getLayout()->renderElement($childName, false); ?> + <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false); ?> <?php endforeach;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index 52e97260420..cf803bbad06 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -6,8 +6,10 @@ // @codingStandardsIgnoreFile +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ + ?> -<a href="#" data-role="remove" data-post-remove='<?php /* @escapeNotVerified */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @escapeNotVerified */ echo __('Remove Item') ?>" class="btn-remove action delete"> - <span><?php /* @escapeNotVerified */ echo __('Remove item');?></span> +<a href="#" data-role="remove" data-post-remove='<?php /* @escapeNotVerified */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @noEscape */ echo __('Remove Item') ?>" class="btn-remove action delete"> + <span><?php /* @noEscape */ echo __('Remove item');?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml index 53205b47f97..3333c68561f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml @@ -6,19 +6,21 @@ // @codingStandardsIgnoreFile +/* @var \Magento\RequisitionList\Block\Catalog\Product\View\Addto\Requisition $block */ + ?> <div class="product-addto-links" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> - <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> + <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <?php $_product = $block->getProduct(); ?> <?php $_compareUrl = $this->helper('Magento\Catalog\Helper\Product\Compare')->getAddUrl($_product); ?> <?php if ($_compareUrl) : ?> <a href="<?php /* @escapeNotVerified */ echo $_compareUrl ?>" class="action tocompare"> - <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span> + <span><?php /* @noEscape */ echo __('Add to Compare') ?></span> </a> <?php endif; ?> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml index 97f6987b194..f757672f931 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml @@ -10,7 +10,7 @@ ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> - <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> + <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <script type="text/x-magento-init"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml index fbb75c0f00a..563e85778f9 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml @@ -17,7 +17,7 @@ $columns = $block->getColumns(); <?php if (count($block->getItems())): ?> <ol class="product-items"> <?php foreach ($block->getItems() as $item): ?> - <?php /* @escapeNotVerified */ echo($iterator++ == 1) ? '<li data-row="product-item" class="product-item" id="item_' . $item->getId() . '">' : '</li><li class="product-item" id="item_' . $item->getId() . '">' ?> + <?php /* @noEscape */ echo($iterator++ == 1) ? '<li data-row="product-item" class="product-item" id="item_' . $block->escapeHtml($item->getId()) . '">' : '</li><li class="product-item" id="item_' . $block->escapeHtml($item->getId()) . '">' ?> <div class="product-item-info"> <?php foreach ($columns as $column): ?> <?php $column->setItem($item); echo $column->toHtml($item);?> @@ -28,7 +28,7 @@ $columns = $block->getColumns(); </ol> <?php else: ?> <div class="message info empty"> - <span><?php /* @escapeNotVerified */ echo __('This Wish List has no Items');?></span> + <span><?php /* @noEscape */ echo __('This Wish List has no Items');?></span> </div> <?php endif; ?> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/link.phtml b/app/code/Magento/Wishlist/view/frontend/templates/link.phtml index 5cfe81e6765..f00901afb05 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/link.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/link.phtml @@ -9,7 +9,7 @@ /* @var $block \Magento\Wishlist\Block\Link */ ?> <li class="link wishlist" data-bind="scope: 'wishlist'"> - <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes() ?>><?php echo $block->escapeHtml($block->getLabel()) ?> + <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>><?php echo $block->escapeHtml($block->getLabel()) ?> <!-- ko if: wishlist().counter --> <span data-bind="text: wishlist().counter" class="counter qty"></span> <!-- /ko --> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml index 254a1eb33fe..52e6ddd1c1f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml @@ -7,4 +7,4 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> -<?php /* @escapeVerified */ echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php /* @escapeNotVerified */ echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); +<?php echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index a0e4c7342c0..b9d83593fdc 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -12,17 +12,17 @@ <?php $options = $block->getOptionList(); ?> <?php if ($options): ?> <div class="tooltip wrapper product-item-tooltip"> - <span class="action details tooltip toggle"><?php /* @escapeNotVerified */ echo __('See Details') ?></span> + <span class="action details tooltip toggle"><?php /* @noEscape */ echo __('See Details') ?></span> <div class="tooltip content"> - <strong class="subtitle"><?php /* @escapeNotVerified */ echo __('Options Details'); ?></strong> + <strong class="subtitle"><?php /* @noEscape */ echo __('Options Details'); ?></strong> <dl> <?php foreach ($options as $option): ?> <dt class="label"><?php echo $block->escapeHtml($option['label']) ?></dt> <dd class="values"> <?php if (is_array($option['value'])): ?> - <?php /* @escapeNotVerified */ echo nl2br(implode("\n", $option['value'])) ?> + <?php echo nl2br($block->escapeHtml(implode("\n", $option['value']))) ?> <?php else: ?> - <?php /* @escapeNotVerified */ echo $option['value'] ?> + <?php echo $block->escapeHtml($option['value']) ?> <?php endif; ?> </dd> <?php endforeach; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml index 30ef4edc393..c44b3ea13dc 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml @@ -10,6 +10,6 @@ ?> <?php if ($block->isRssAllowed() && $block->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?> <a href="<?php /* @escapeNotVerified */ echo $block->getLink(); ?>" class="action rss wishlist"> - <span><?php /* @escapeNotVerified */ echo __('RSS Feed') ?></span> + <span><?php /* @noEscape */ echo __('RSS Feed') ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index 3f6fc322b0e..e7d1bc86825 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -13,12 +13,12 @@ <form class="form shared wishlist" action="<?php /* @escapeNotVerified */ echo $block->getUrl('wishlist/index/update') ?>" method="post"> <div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Wish List'); ?></caption> + <caption class="table-caption"><?php /* @noEscape */ echo __('Wish List'); ?></caption> <thead> <tr> - <th class="col product" scope="col"><?php /* @escapeNotVerified */ echo __('Product') ?></th> - <th class="col comment" scope="col"><?php /* @escapeNotVerified */ echo __('Comment') ?></th> - <th class="col actions" scope="col"><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></th> + <th class="col product" scope="col"><?php /* @noEscape */ echo __('Product') ?></th> + <th class="col comment" scope="col"><?php /* @noEscape */ echo __('Comment') ?></th> + <th class="col actions" scope="col"><?php /* @noEscape */ echo __('Add to Cart') ?></th> </tr> </thead> <tbody> @@ -47,20 +47,20 @@ ?> <?php echo $block->getDetailsHtml($item) ?> </td> - <td data-th="<?php echo $block->escapeHtml(__('Comment')) ?>" class="col comment"><?php /* @escapeNotVerified */ echo $block->getEscapedDescription($item) ?></td> + <td data-th="<?php echo $block->escapeHtml(__('Comment')) ?>" class="col comment"><?php /* @noEscape */ echo $block->getEscapedDescription($item) ?></td> <td data-th="<?php echo $block->escapeHtml(__('Add to Cart')) ?>" class="col actions" data-role="add-to-links"> <?php if ($product->isSaleable()): ?> <?php if ($isVisibleProduct): ?> <button type="button" - title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>" + title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-post='<?php /* @escapeNotVerified */ echo $block->getSharedItemAddToCartUrl($item); ?>' class="action tocart"> - <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> + <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> </button> <?php endif ?> <?php endif; ?> <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> - <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> + <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> </a> </td> </tr> @@ -73,20 +73,20 @@ <?php if ($block->isSaleable()):?> <div class="primary"> <button type="button" - title="<?php /* @escapeNotVerified */ echo __('Add All to Cart') ?>" + title="<?php /* @noEscape */ echo __('Add All to Cart') ?>" data-post='<?php /* @escapeNotVerified */ echo $block->getSharedAddAllToCartUrl(); ?>' class="action tocart primary"> - <span><?php /* @escapeNotVerified */ echo __('Add All to Cart') ?></span> + <span><?php /* @noEscape */ echo __('Add All to Cart') ?></span> </button> </div> <?php endif;?> <div class="secondary"> <a href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>" class="action back"> - <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> + <span><?php /* @noEscape */ echo __('Back') ?></span> </a> </div> </div> </form> <?php else: ?> - <div class="message info empty"><div><?php /* @escapeNotVerified */ echo __('Wish List is empty now.') ?></div></div> + <div class="message info empty"><div><?php /* @noEscape */ echo __('Wish List is empty now.') ?></div></div> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index 6ddf8974e22..ae32b8c581a 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -12,29 +12,29 @@ action="<?php /* @escapeNotVerified */ echo $block->getSendUrl() ?>" id="form-validate" method="post" - data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" + data-hasrequired="<?php /* @noEscape */ echo __('* Required Fields') ?>" data-mage-init='{"validation":{}}'> <fieldset class="fieldset"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Sharing Information') ?></span></legend><br /> + <legend class="legend"><span><?php /* @noEscape */ echo __('Sharing Information') ?></span></legend><br /> <div class="field emails required"> - <label class="label" for="email_address"><span><?php /* @escapeNotVerified */ echo __('Email addresses, separated by commas') ?></span></label> + <label class="label" for="email_address"><span><?php /* @noEscape */ echo __('Email addresses, separated by commas') ?></span></label> <div class="control"> - <textarea name="emails" cols="60" rows="5" id="email_address" data-validate="{required:true,'validate-emails':true}"><?php /* @escapeNotVerified */ echo $block->getEnteredData('emails') ?></textarea> + <textarea name="emails" cols="60" rows="5" id="email_address" data-validate="{required:true,'validate-emails':true}"><?php /* @noEscape */ echo $block->getEnteredData('emails') ?></textarea> </div> </div> <div class="field text"> - <label class="label" for="message"><span><?php /* @escapeNotVerified */ echo __('Message') ?></span></label> + <label class="label" for="message"><span><?php /* @noEscape */ echo __('Message') ?></span></label> <div class="control"> - <textarea id="message" name="message" cols="60" rows="5"><?php /* @escapeNotVerified */ echo $block->getEnteredData('message') ?></textarea> + <textarea id="message" name="message" cols="60" rows="5"><?php /* @noEscape */ echo $block->getEnteredData('message') ?></textarea> </div> </div> <?php if ($this->helper('Magento\Wishlist\Helper\Rss')->isRssAllow()): ?> <div class="field choice rss"> - <input type="checkbox" name="rss_url" id="rss_url" value="1" title="<?php /* @escapeNotVerified */ echo __('Check here to link an RSS feed to your Wish List.') ?>" class="checkbox"> + <input type="checkbox" name="rss_url" id="rss_url" value="1" title="<?php /* @noEscape */ echo __('Check here to link an RSS feed to your Wish List.') ?>" class="checkbox"> <label class="label" for="rss_url"> <span> - <?php /* @escapeNotVerified */ echo __('Check here to link an RSS feed to your Wish List.') ?> + <?php /* @noEscape */ echo __('Check here to link an RSS feed to your Wish List.') ?> </span> </label> </div> @@ -42,12 +42,12 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action submit primary"> - <span><?php /* @escapeNotVerified */ echo __('Share Wish List') ?></span> + <button type="submit" title="<?php /* @noEscape */ echo __('Share Wish List') ?>" class="action submit primary"> + <span><?php /* @noEscape */ echo __('Share Wish List') ?></span> </button> </div> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl(); ?>"><span><?php /* @escapeNotVerified */ echo __('Back')?></span></a> + <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl(); ?>"><span><?php /* @noEscape */ echo __('Back')?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml index 022c61ce8a2..c333deb1923 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml @@ -14,13 +14,13 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <?php if ($wishlistHelper->isAllow()) : ?> <div class="block block-wishlist" data-bind="scope: 'wishlist'"> <div class="block-title"> - <strong role="heading" aria-level="2"><?php /* @escapeNotVerified */ echo $block->getTitle(); ?></strong> + <strong role="heading" aria-level="2"><?php /* @noEscape */ echo $block->getTitle(); ?></strong> <!-- ko if: wishlist().counter --> <span data-bind="text: wishlist().counter" class="counter"></span> <!-- /ko --> </div> <div class="block-content"> - <strong class="subtitle"><?php /* @escapeNotVerified */ echo __('Last Added Items') ?></strong> + <strong class="subtitle"><?php /* @noEscape */ echo __('Last Added Items') ?></strong> <!-- ko if: wishlist().counter --> <ol class="product-items no-display" id="wishlist-sidebar" data-bind="foreach: wishlist().items, css: {'no-display': null}"> <li class="product-item"> @@ -39,18 +39,18 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <!-- ko if: product_is_saleable_and_visible --> <div class="actions-primary"> <!-- ko if: product_has_required_options --> - <a href="#" data-bind="attr: {'data-post': add_to_cart_params}" class="action tocart primary"><span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span></a> + <a href="#" data-bind="attr: {'data-post': add_to_cart_params}" class="action tocart primary"><span><?php /* @noEscape */ echo __('Add to Cart') ?></span></a> <!-- /ko --> <!-- ko ifnot: product_has_required_options --> - <button type="button" class="action tocart primary" data-bind="attr: {'data-post': add_to_cart_params}"><span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span></button> + <button type="button" class="action tocart primary" data-bind="attr: {'data-post': add_to_cart_params}"><span><?php /* @noEscape */ echo __('Add to Cart') ?></span></button> <!-- /ko --> </div> <!-- /ko --> <div class="actions-secondary"> <a href="#" data-bind="attr: {'data-post': delete_item_params}" - title="<?php /* @escapeNotVerified */ echo __('Remove This Item') ?>" + title="<?php /* @noEscape */ echo __('Remove This Item') ?>" class="btn-remove action delete"> - <span><?php /* @escapeNotVerified */ echo __('Remove This Item') ?></span> + <span><?php /* @noEscape */ echo __('Remove This Item') ?></span> </a> </div> </div> @@ -62,12 +62,12 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <div class="primary"> <a class="action details" href="<?php /* @escapeNotVerified */ echo $this->helper('Magento\Wishlist\Helper\Data')->getListUrl() ?>" - title="<?php /* @escapeNotVerified */ echo __('Go to Wish List') ?>"><span><?php /* @escapeNotVerified */ echo __('Go to Wish List') ?></span></a> + title="<?php /* @noEscape */ echo __('Go to Wish List') ?>"><span><?php /* @noEscape */ echo __('Go to Wish List') ?></span></a> </div> </div> <!-- /ko --> <!-- ko ifnot: wishlist().counter --> - <div class="empty"><?php /* @escapeNotVerified */ echo __('You have no items in your wish list.') ?></div> + <div class="empty"><?php /* @noEscape */ echo __('You have no items in your wish list.') ?></div> <!-- /ko --> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml index 31217431a4e..5f2eef48307 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml @@ -23,7 +23,7 @@ <?php $block->getChildBlock('items')->setItems($block->getWishlistItems()); ?> <?php echo $block->getChildHtml('items');?> <?php else: ?> - <div class="message info empty"><span><?php /* @escapeNotVerified */ echo __('You have no items in your wish list.') ?></span></div> + <div class="message info empty"><span><?php /* @noEscape */ echo __('You have no items in your wish list.') ?></span></div> <?php endif ?> <?php echo $block->getChildHtml('bottom'); ?> <div class="actions-toolbar"> @@ -32,7 +32,7 @@ </div> <div class="secondary"> <a href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>" class="action back"> - <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> + <span><?php /* @noEscape */ echo __('Back') ?></span> </a> </div> </div> diff --git a/lib/internal/Magento/Framework/View/Element/Html/Link.php b/lib/internal/Magento/Framework/View/Element/Html/Link.php index c4e5460c7de..c5aba22bad7 100644 --- a/lib/internal/Magento/Framework/View/Element/Html/Link.php +++ b/lib/internal/Magento/Framework/View/Element/Html/Link.php @@ -59,7 +59,7 @@ class Link extends \Magento\Framework\View\Element\Template foreach ($this->allowedAttributes as $attribute) { $value = $this->getDataUsingMethod($attribute); if ($value !== null) { - $attributes[$attribute] = $this->escapeHtml($value); + $attributes[$this->escapeHtml($attribute)] = $this->escapeHtml($value); } } -- GitLab From d06163af9a243853fe50e04b376aaa035c204e1b Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Mon, 1 Aug 2016 17:34:11 +0300 Subject: [PATCH 089/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - set focus on form first invalid input --- .../view/frontend/web/js/view/shipping.js | 53 ++--------------- .../view/base/web/js/form/element/abstract.js | 8 +++ .../Magento/Ui/view/base/web/js/form/form.js | 57 +++++++++++++++++-- 3 files changed, 67 insertions(+), 51 deletions(-) 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 5c99c179592..de9611f4a33 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 @@ -69,17 +69,17 @@ define( isNewAddressAdded: ko.observable(false), saveInAddressBook: 1, quoteIsVirtual: quote.isVirtual(), - fieldsetName: 'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset', /** * @return {exports} */ initialize: function () { var self = this, - hasNewAddress; + hasNewAddress, + fieldsetName = 'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset'; this._super(); - shippingRatesValidator.initFields(this.fieldsetName); + shippingRatesValidator.initFields(fieldsetName); if (!quote.isVirtual()) { stepNavigator.registerStep( @@ -239,8 +239,7 @@ define( var shippingAddress, addressData, loginFormSelector = 'form[data-role=email-with-possible-login]', - emailValidationResult = customer.isLoggedIn(), - fieldset; + emailValidationResult = customer.isLoggedIn(); if (!quote.shippingMethod()) { this.errorValidationMessage($.mage.__('Please specify a shipping method.')); @@ -257,15 +256,6 @@ define( this.source.set('params.invalid', false); this.source.trigger('shippingAddress.data.validate'); - // In case of form is invalid - // get first error and focus it - if (this.source.get('params.invalid')) { - fieldset = registry.get(this.fieldsetName); - if (fieldset && typeof fieldset.elems === 'function') { - this._focusFormErrors(fieldset.elems()); - } - } - if (this.source.get('shippingAddress.custom_attributes')) { this.source.trigger('shippingAddress.custom_attributes.data.validate'); } @@ -275,6 +265,8 @@ define( !quote.shippingMethod().method_code || !quote.shippingMethod().carrier_code ) { + this.focusInvalid(); + return false; } } @@ -313,39 +305,6 @@ define( } return true; - }, - - /** - * Recursive check collection of elements for errors and set related focus - * - * @param collection - * @returns {boolean} - * @private - */ - _focusFormErrors: function (collection) { - var i, - item, - skipCheck = false; - - for (i in collection) { - if (!collection.hasOwnProperty(i)) { - continue; - } - - item = collection[i]; - if (typeof item.elems === 'function') { - skipCheck = this._focusFormErrors(item.elems()); - } - - if (!skipCheck) { - if (typeof item.error === 'function' && item.error() && typeof item.focused === 'function') { - item.focused(true); - return true; - } - } - } - - return false; } }); } diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 270e8a2c3a1..c3f7884f54e 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -74,6 +74,14 @@ define([ return this; }, + /** + * Checks if component has error. + * @returns {Boolean} + */ + isInvalid: function () { + return this.error() && this.error().length; + }, + /** * Initializes observable properties of instance * diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js index 672af8a7ed8..7cec82ac8e3 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -248,17 +248,66 @@ define([ * @param {Object} data */ save: function (redirect, data) { - var scrollTop; - this.validate(); if (!this.additionalInvalid && !this.source.get('params.invalid')) { this.setAdditionalData(data) .submit(redirect); } else { - scrollTop = $(this.errorClass).offset().top - window.innerHeight / 2; - window.scrollTo(0, scrollTop); + this.focusInvalid(); + } + }, + + /** + * Tries to set focus on first invalid form field. + * + * @returns {Object} + */ + focusInvalid: function () { + var scrollTop, invalidField = this.some('isInvalid'); + + if (typeof invalidField !== 'undefined') { + if (typeof invalidField.focused === 'function') { + invalidField.focused(true); + } else { + scrollTop = $(this.errorClass).offset().top - window.innerHeight / 2; + window.scrollTo(0, scrollTop); + } + } + + return this; + }, + + /** + * Tries to call specified method on an object or its children. + * Returns first object which pass the method test. + * + * @param {String} method - name of method for test + * @param {Object} [obj] - target object + * @returns {*} + */ + some: function (method, obj) { + var i, result, collection; + + obj = obj || this; + + if (_.isFunction(obj[method]) && obj[method]()) { + result = obj; } + + if (!result) { + collection = typeof obj.elems === 'function' ? obj.elems() : []; + + for (i in collection) { + if (collection.hasOwnProperty(i)) { + if (result = this.some(method, collection[i])) { + break; + } + } + } + } + + return result; }, /** -- GitLab From eb1d604353ee0bc8744bb243d5127c87c02f4c52 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Mon, 1 Aug 2016 18:38:14 +0300 Subject: [PATCH 090/838] MAGETWO-55754: [WCAG 2.0 AA] Image Gallery Thumbnails - "Skip Gallery" link --- .../view/frontend/layout/catalog_product_view.xml | 13 +++++++++++++ .../blank/Magento_Theme/web/css/source/_module.less | 5 +++++ .../luma/Magento_Theme/web/css/source/_module.less | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml index 991d9a36d18..730b9089da3 100644 --- a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml +++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml @@ -101,7 +101,20 @@ </block> </container> <container name="product.info.media" htmlTag="div" htmlClass="product media" after="product.info.main"> + <container name="skip_gallery.wrapper" htmlTag="div" htmlClass="action-skip-wrapper"> + <block class="Magento\Framework\View\Element\Template" before="product.info.media.image" name="skip_gallery" template="Magento_Theme::html/skip.phtml"> + <arguments> + <argument name="target" xsi:type="string">nextarea</argument> + <argument name="label" translate="true" xsi:type="string">Skip Gallery</argument> + </arguments> + </block> + </container> <block class="Magento\Catalog\Block\Product\View\Gallery" name="product.info.media.image" template="product/view/gallery.phtml"/> + <block class="Magento\Framework\View\Element\Template" name="skip_gallery.target" after="product.info.media.image" template="Magento_Theme::html/skiptarget.phtml"> + <arguments> + <argument name="target_id" xsi:type="string">nextarea</argument> + </arguments> + </block> </container> <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.details" template="product/view/details.phtml" after="product.info.media"> <block class="Magento\Catalog\Block\Product\View\Description" name="product.info.description" template="product/view/attribute.phtml" group="detailed_info"> diff --git a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less index 3b8e84da841..41b2730ca58 100644 --- a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less @@ -112,6 +112,11 @@ } } + .action-skip-wrapper { + position: relative; + height: 0; + } + // // Global notice // --------------------------------------------- diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less index 5581eb7fb05..cb7e3ef0c44 100644 --- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less @@ -168,6 +168,11 @@ } } + .action-skip-wrapper { + position: relative; + height: 0; + } + // // Global notice // --------------------------------------------- -- GitLab From 61e0be6276d43a6997080e693216b63b53f8a635 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 1 Aug 2016 11:51:37 -0500 Subject: [PATCH 091/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../frontend/templates/address/book.phtml | 12 +-- .../frontend/templates/address/edit.phtml | 51 +++++----- .../templates/form/confirmation.phtml | 4 +- .../view/frontend/templates/form/edit.phtml | 6 +- .../templates/form/forgotpassword.phtml | 6 +- .../view/frontend/templates/form/login.phtml | 6 +- .../frontend/templates/form/newsletter.phtml | 2 +- .../frontend/templates/form/register.phtml | 36 +++---- .../form/resetforgottenpassword.phtml | 6 +- .../frontend/templates/js/customer-data.phtml | 2 +- .../templates/js/section-config.phtml | 2 +- .../view/frontend/templates/widget/dob.phtml | 6 +- .../frontend/templates/widget/gender.phtml | 6 +- .../view/frontend/templates/widget/name.phtml | 94 +++++++++---------- .../frontend/templates/widget/taxvat.phtml | 4 +- 15 files changed, 121 insertions(+), 122 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index d2ba98781c3..a0a003904fc 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -27,7 +27,7 @@ </address> </div> <div class="box-actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getAddressEditUrl($_pAddsses) ?>"> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressEditUrl($_pAddsses)) ?>"> <span><?php /* @escapeNotVerified */ echo __('Change Billing Address') ?></span> </a> </div> @@ -52,7 +52,7 @@ </address> </div> <div class="box-actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getAddressEditUrl($_pAddsses) ?>"> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressEditUrl($_pAddsses)) ?>"> <span><?php /* @escapeNotVerified */ echo __('Change Shipping Address') ?></span> </a> </div> @@ -79,8 +79,8 @@ <?php echo $block->getAddressHtml($_address) ?><br /> </address> <div class="item actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getUrl('customer/address/edit', ['id' => $_address->getId()]) ?>"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> - <a class="action delete" href="#" role="delete-address" data-address="<?php /* @escapeNotVerified */ echo $_address->getId() ?>"><span><?php /* @escapeNotVerified */ echo __('Delete Address') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('customer/address/edit', ['id' => $_address->getId()])) ?>"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> + <a class="action delete" href="#" role="delete-address" data-address="<?php echo $block->escapeHtmlAttr($_address->getId()) ?>"><span><?php /* @escapeNotVerified */ echo __('Delete Address') ?></span></a> </div> </li> <?php endforeach; ?> @@ -104,9 +104,9 @@ ".page-main": { "address": { "deleteAddress": "li.item a[role='delete-address']", - "deleteUrlPrefix": "<?php /* @escapeNotVerified */ echo $block->getDeleteUrl() ?>id/", + "deleteUrlPrefix": "<?php echo $block->escapeUrl($block->getDeleteUrl()) ?>id/", "addAddress": "button[role='add-address']", - "addAddressLocation": "<?php /* @escapeNotVerified */ echo $block->getAddAddressUrl() ?>" + "addAddressLocation": "<?php echo $block->escapeUrl($block->getAddAddressUrl()) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index 876ca049d92..f8e65778b78 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -15,7 +15,7 @@ */ ?> <form class="form-address-edit" - action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" + action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" method="post" id="form-validate" enctype="multipart/form-data" @@ -23,8 +23,8 @@ <fieldset class="fieldset"> <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Contact Information') ?></span></legend><br> <?php echo $block->getBlockHtml('formkey')?> - <input type="hidden" name="success_url" value="<?php /* @escapeNotVerified */ echo $block->getSuccessUrl() ?>"> - <input type="hidden" name="error_url" value="<?php /* @escapeNotVerified */ echo $block->getErrorUrl() ?>"> + <input type="hidden" name="success_url" value="<?php echo $block->escapeUrl($block->getSuccessUrl()) ?>"> + <input type="hidden" name="error_url" value="<?php echo $block->escapeUrl($block->getErrorUrl()) ?>"> <?php echo $block->getNameBlockHtml() ?> <div class="field company"> <label class="label" for="company"><span><?php /* @escapeNotVerified */ echo __('Company') ?></span></label> @@ -33,8 +33,8 @@ name="company" id="company" title="<?php /* @escapeNotVerified */ echo __('Company') ?>" - value="<?php echo $block->escapeHtml($block->getAddress()->getCompany()) ?>" - class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company') ?>"> + value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getCompany()) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company')) ?>"> </div> </div> <div class="field telephone required"> @@ -44,9 +44,9 @@ <div class="control"> <input type="text" name="telephone" - value="<?php echo $block->escapeHtml($block->getAddress()->getTelephone()) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getTelephone()) ?>" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>" + class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone')) ?>" id="telephone"> </div> </div> @@ -57,8 +57,8 @@ name="fax" id="fax" title="<?php /* @escapeNotVerified */ echo __('Fax') ?>" - value="<?php echo $block->escapeHtml($block->getAddress()->getFax()) ?>" - class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('fax') ?>"> + value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getFax()) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('fax')) ?>"> </div> </div> </fieldset> @@ -72,11 +72,10 @@ <div class="control"> <input type="text" name="street[]" - value="<?php echo $block->escapeHtml($block->getStreetLine(1)) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getStreetLine(1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address') ?>" id="street_1" - class="input-text <?php /* @escapeNotVerified */ - echo $_streetValidationClass ?>"/> + class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"/> <div class="nested"> <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?> <?php for ($_i = 1, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i < $_n; $_i++): ?> @@ -86,9 +85,9 @@ </label> <div class="control"> <input type="text" name="street[]" - value="<?php echo $block->escapeHtml($block->getStreetLine($_i + 1)) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getStreetLine($_i + 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i + 1) ?>" - id="street_<?php /* @escapeNotVerified */ echo $_i + 1 ?>" echo $_streetValidationClass ?>"> + id="street_<?php /* @escapeNotVerified */ echo $_i + 1 ?>" <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> </div> <?php endfor; ?> @@ -104,9 +103,9 @@ <div class="control"> <input type="text" name="vat_id" - value="<?php echo $block->escapeHtml($block->getAddress()->getVatId()) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getVatId()) ?>" title="<?php /* @escapeNotVerified */ echo __('VAT Number') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('vat_id') ?>" + class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('vat_id')) ?>" id="vat_id"> </div> </div> @@ -116,9 +115,9 @@ <div class="control"> <input type="text" name="city" - value="<?php echo $block->escapeHtml($block->getAddress()->getCity()) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getCity()) ?>" title="<?php /* @escapeNotVerified */ echo __('City') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city') ?>" + class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city')) ?>" id="city"> </div> </div> @@ -129,15 +128,15 @@ <div class="control"> <select id="region_id" name="region_id" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" - class="validate-select" <?php echo (!$block->getConfig('general/region/display_all')) ? ' disabled="disabled"' : ''; ?>> + class="validate-select" <?php echo !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : ''; ?>> <option value=""><?php /* @escapeNotVerified */ echo __('Please select a region, state or province.') ?></option> </select> <input type="text" id="region" name="region" - value="<?php echo $block->escapeHtml($block->getRegion()) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getRegion()) ?>" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region') ?>"<?php echo (!$block->getConfig('general/region/display_all')) ? ' disabled="disabled"' : ''; ?>/> + class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>"<?php echo !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : ''; ?>/> </div> </div> <div class="field zip required"> @@ -147,10 +146,10 @@ <div class="control"> <input type="text" name="postcode" - value="<?php echo $block->escapeHtml($block->getAddress()->getPostcode()) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getPostcode()) ?>" title="<?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?>" id="zip" - class="input-text validate-zip-international <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode') ?>"> + class="input-text validate-zip-international <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode')) ?>"> </div> </div> <div class="field country required"> @@ -213,14 +212,14 @@ }, "#country": { "regionUpdater": { - "optionalRegionAllowed": <?php /* @escapeNotVerified */ echo($block->getConfig('general/region/display_all') ? 'true' : 'false'); ?>, + "optionalRegionAllowed": <?php /* @noEscape */ $block->getConfig('general/region/display_all') ? 'true' : 'false'; ?>, "regionListId": "#region_id", "regionInputId": "#region", "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php /* @escapeNotVerified */ echo $block->getRegionId() ?>", - "countriesWithOptionalZip": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> + "defaultRegion": "<?php echo $block->escapeHtmlAttr($block->getRegionId()) ?>", + "countriesWithOptionalZip": <?php echo $block->escapeHtmlAttr($this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true)) ?> } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml index f7775ec3f14..58ce17d7137 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml @@ -13,7 +13,7 @@ <div class="field email required"> <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input type="email" name="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtml($block->getEmail()) ?>" data-validate="{required:true, 'validate-email':true}"> + <input type="email" name="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtmlAttr($block->getEmail()) ?>" data-validate="{required:true, 'validate-email':true}"> </div> </div> </fieldset> @@ -22,7 +22,7 @@ <button type="submit" class="action send primary"><span><?php /* @escapeNotVerified */ echo __('Send confirmation link') ?></span></button> </div> <div class="secondary"> - <a href="<?php /* @escapeNotVerified */ echo $block->getLoginUrl() ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Sign In') ?></span></a> + <a href="<?php echo $block->escapeUrl($block->getLoginUrl()) ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Sign In') ?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 669cba366f2..89219df0e78 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -8,7 +8,7 @@ /** @var \Magento\Customer\Block\Form\Edit $block */ ?> -<form class="form form-edit-account" action="<?php /* @escapeNotVerified */ echo $block->getUrl('customer/account/editPost') ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" autocomplete="off"> +<form class="form form-edit-account" action="<?php echo $block->escapeUrl($block->getUrl('customer/account/editPost')) ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" autocomplete="off"> <fieldset class="fieldset info"> <?php echo $block->getBlockHtml('formkey')?> <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Account Information') ?></span></legend><br> @@ -41,7 +41,7 @@ <div class="field email required" data-container="change-email"> <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input type="email" name="email" id="email" autocomplete="email" data-input="change-email" value="<?php echo $block->escapeHtml($block->getCustomer()->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" class="input-text" data-validate="{required:true, 'validate-email':true}" /> + <input type="email" name="email" id="email" autocomplete="email" data-input="change-email" value="<?php echo $block->escapeHtmlAttr($block->getCustomer()->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" class="input-text" data-validate="{required:true, 'validate-email':true}" /> </div> </div> <div class="field password current required"> @@ -94,7 +94,7 @@ "mage/mage" ], function($){ var dataForm = $('#form-validate'); - var ignore = <?php /* @escapeNotVerified */ echo $_dob->isEnabled() ? '\'input[id$="full"]\'' : 'null'; ?>; + var ignore = <?php /* @noEscape */ echo $_dob->isEnabled() ? '\'input[id$="full"]\'' : 'null'; ?>; dataForm.mage('validation', { <?php if ($_dob->isEnabled()): ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml index 0b91f6db8cc..9361fb5871f 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml @@ -10,7 +10,7 @@ ?> <form class="form password forget" - action="<?php /* @escapeNotVerified */ echo $block->getUrl('*/*/forgotpasswordpost') ?>" + action="<?php echo $block->escapeUrl($block->getUrl('*/*/forgotpasswordpost')) ?>" method="post" id="form-validate" data-mage-init='{"validation":{}}'> @@ -19,7 +19,7 @@ <div class="field email required"> <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input type="email" name="email" alt="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtml($block->getEmailValue()) ?>" data-validate="{required:true, 'validate-email':true}"> + <input type="email" name="email" alt="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtmlAttr($block->getEmailValue()) ?>" data-validate="{required:true, 'validate-email':true}"> </div> </div> <?php echo $block->getChildHtml('form_additional_info'); ?> @@ -29,7 +29,7 @@ <button type="submit" class="action submit primary"><span><?php /* @escapeNotVerified */ echo __('Reset My Password') ?></span></button> </div> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getLoginUrl() ?>"><span><?php /* @escapeNotVerified */ echo __('Go back') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getLoginUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Go back') ?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index f746af89c66..b24013b18b3 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -22,7 +22,7 @@ </div> <div class="block-content" aria-labelledby="block-customer-login-heading"> <form class="form form-login" - action="<?php /* @escapeNotVerified */ echo $block->getPostActionUrl() ?>" + action="<?php echo $block->escapeUrl($block->getPostActionUrl()) ?>" method="post" id="login-form" data-mage-init='{"validation":{}}'> @@ -32,7 +32,7 @@ <div class="field email required"> <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input name="login[username]" value="<?php echo $block->escapeHtml($block->getUsername()) ?>" <?php if ($block->isAutocompleteDisabled()) :?> autocomplete="off"<?php endif; ?> id="email" type="email" class="input-text" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" data-validate="{required:true, 'validate-email':true}"> + <input name="login[username]" value="<?php echo $block->escapeHtmlAttr($block->getUsername()) ?>" <?php if ($block->isAutocompleteDisabled()) :?> autocomplete="off"<?php endif; ?> id="email" type="email" class="input-text" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" data-validate="{required:true, 'validate-email':true}"> </div> </div> <div class="field password required"> @@ -44,7 +44,7 @@ <?php echo $block->getChildHtml('form_additional_info'); ?> <div class="actions-toolbar"> <div class="primary"><button type="submit" class="action login primary" name="send" id="send2"><span><?php /* @escapeNotVerified */ echo __('Sign In') ?></span></button></div> - <div class="secondary"><a class="action remind" href="<?php /* @escapeNotVerified */ echo $block->getForgotPasswordUrl() ?>"><span><?php /* @escapeNotVerified */ echo __('Forgot Your Password?') ?></span></a></div> + <div class="secondary"><a class="action remind" href="<?php echo $block->escapeHtmlAttr($block->getForgotPasswordUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Forgot Your Password?') ?></span></a></div> </div> </fieldset> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml index c8a77322bcd..c432da2ac04 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml @@ -8,7 +8,7 @@ ?> <?php echo $block->getChildHtml('form_before')?> - <form class="form form-newsletter-manage" action="<?php /* @escapeNotVerified */ echo $block->getAction() ?>" method="post" id="form-validate"> + <form class="form form-newsletter-manage" action="<?php echo $block->escapeUrl($block->getAction()) ?>" method="post" id="form-validate"> <fieldset class="fieldset"> <?php echo $block->getBlockHtml('formkey')?> <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Subscription option') ?></span></legend><br> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index 264a3acefd9..842febeec50 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -17,11 +17,11 @@ <?php echo $block->getChildHtml('form_fields_before')?> <?php /* Extensions placeholder */ ?> <?php echo $block->getChildHtml('customer.form.register.extra')?> -<form class="form create account form-create-account" action="<?php /* @escapeNotVerified */ echo $block->getPostActionUrl() ?>" method="post" id="form-validate" enctype="multipart/form-data" autocomplete="off"> +<form class="form create account form-create-account" action="<?php echo $block->escapeUrl($block->getPostActionUrl()) ?>" method="post" id="form-validate" enctype="multipart/form-data" autocomplete="off"> <fieldset class="fieldset create info"> <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Personal Information') ?></span></legend><br> - <input type="hidden" name="success_url" value="<?php /* @escapeNotVerified */ echo $block->getSuccessUrl() ?>"> - <input type="hidden" name="error_url" value="<?php /* @escapeNotVerified */ echo $block->getErrorUrl() ?>"> + <input type="hidden" name="success_url" value="<?php echo $block->escapeUrl($block->getSuccessUrl()) ?>"> + <input type="hidden" name="error_url" value="<?php echo $block->escapeUrl($block->getErrorUrl()) ?>"> <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name')->setObject($block->getFormData())->setForceUseCustomerAttributes(true)->toHtml() ?> <?php if ($block->isNewsletterEnabled()): ?> <div class="field choice newsletter"> @@ -54,13 +54,13 @@ <div class="field company"> <label for="company" class="label"><span><?php /* @escapeNotVerified */ echo __('Company') ?></span></label> <div class="control"> - <input type="text" name="company" id="company" value="<?php echo $block->escapeHtml($block->getFormData()->getCompany()) ?>" title="<?php /* @escapeNotVerified */ echo __('Company') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company') ?>"> + <input type="text" name="company" id="company" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getCompany()) ?>" title="<?php /* @escapeNotVerified */ echo __('Company') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company')) ?>"> </div> </div> <div class="field telephone"> <label for="telephone" class="label"><span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span></label> <div class="control"> - <input type="text" name="telephone" id="telephone" value="<?php echo $block->escapeHtml($block->getFormData()->getTelephone()) ?>" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>"> + <input type="text" name="telephone" id="telephone" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getTelephone()) ?>" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>"> </div> </div> @@ -69,7 +69,7 @@ <div class="field street required"> <label for="street_1" class="label"><span><?php /* @escapeNotVerified */ echo __('Street Address') ?></span></label> <div class="control"> - <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreet(0)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address') ?>" id="street_1" class="input-text <?php /* @escapeNotVerified */ echo $_streetValidationClass ?>"> + <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getStreet(0)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address') ?>" id="street_1" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> <div class="nested"> <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?> <?php for ($_i = 2, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i <= $_n; $_i++): ?> @@ -78,7 +78,7 @@ <span><?php /* @escapeNotVerified */ echo __('Address') ?></span> </label> <div class="control"> - <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreetLine($_i - 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i) ?>" id="street_<?php /* @escapeNotVerified */ echo $_i ?>" class="input-text <?php /* @escapeNotVerified */ echo $_streetValidationClass ?>"> + <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreetLine($_i - 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i) ?>" id="street_<?php /* @escapeNotVerified */ echo $_i ?>" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> </div> <?php endfor; ?> @@ -89,7 +89,7 @@ <div class="field required"> <label for="city" class="label"><span><?php /* @escapeNotVerified */ echo __('City') ?></span></label> <div class="control"> - <input type="text" name="city" value="<?php echo $block->escapeHtml($block->getFormData()->getCity()) ?>" title="<?php /* @escapeNotVerified */ echo __('City') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city') ?>" id="city"> + <input type="text" name="city" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getCity()) ?>" title="<?php /* @escapeNotVerified */ echo __('City') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city')) ?>" id="city"> </div> </div> @@ -99,14 +99,14 @@ <select id="region_id" name="region_id" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" class="validate-select" style="display:none;"> <option value=""><?php /* @escapeNotVerified */ echo __('Please select a region, state or province.') ?></option> </select> - <input type="text" id="region" name="region" value="<?php echo $block->escapeHtml($block->getRegion()) ?>" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region') ?>" style="display:none;"> + <input type="text" id="region" name="region" value="<?php echo $block->escapeHtml($block->getRegion()) ?>" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>" style="display:none;"> </div> </div> <div class="field zip required"> <label for="zip" class="label"><span><?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?></span></label> <div class="control"> - <input type="text" name="postcode" value="<?php echo $block->escapeHtml($block->getFormData()->getPostcode()) ?>" title="<?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?>" id="zip" class="input-text validate-zip-international <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode') ?>"> + <input type="text" name="postcode" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getPostcode()) ?>" title="<?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?>" id="zip" class="input-text validate-zip-international <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode')) ?>"> </div> </div> @@ -133,7 +133,7 @@ <div class="field required"> <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input type="email" name="email" autocomplete="email" id="email_address" value="<?php echo $block->escapeHtml($block->getFormData()->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" class="input-text" data-validate="{required:true, 'validate-email':true}"> + <input type="email" name="email" autocomplete="email" id="email_address" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" class="input-text" data-validate="{required:true, 'validate-email':true}"> </div> </div> <div class="field password required" data-mage-init='{"passwordStrengthIndicator": {}}'> @@ -142,8 +142,8 @@ <input type="password" name="password" id="password" title="<?php /* @escapeNotVerified */ echo __('Password') ?>" class="input-text" - data-password-min-length="<?php echo $block->escapeHtml($block->getMinimumPasswordLength()) ?>" - data-password-min-character-sets="<?php echo $block->escapeHtml($block->getRequiredCharacterClassesNumber()) ?>" + data-password-min-length="<?php echo $block->escapeHtmlAttr($block->getMinimumPasswordLength()) ?>" + data-password-min-character-sets="<?php echo $block->escapeHtmlAttr($block->getRequiredCharacterClassesNumber()) ?>" data-validate="{required:true, 'validate-customer-password':true}" autocomplete="off"> <div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite"> @@ -181,7 +181,7 @@ require([ ], function($){ var dataForm = $('#form-validate'); - var ignore = <?php /* @escapeNotVerified */ echo $_dob->isEnabled() ? '\'input[id$="full"]\'' : 'null'; ?>; + var ignore = <?php /* @noEscape */ echo $_dob->isEnabled() ? '\'input[id$="full"]\'' : 'null'; ?>; dataForm.mage('validation', { <?php if ($_dob->isEnabled()): ?> @@ -210,14 +210,14 @@ require([ { "#country": { "regionUpdater": { - "optionalRegionAllowed": <?php /* @escapeNotVerified */ echo($block->getConfig('general/region/display_all') ? 'true' : 'false'); ?>, + "optionalRegionAllowed": <?php /* @noEscape */ echo $block->getConfig('general/region/display_all') ? 'true' : 'false'; ?>, "regionListId": "#region_id", "regionInputId": "#region", "postcodeId": "#zip", "form": "#form-validate", - "regionJson": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php /* @escapeNotVerified */ echo $block->getFormData()->getRegionId() ?>", - "countriesWithOptionalZip": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> + "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, + "defaultRegion": "<?php echo $block->escapeJs($block->getFormData()->getRegionId()) ?>", + "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml index 6fba6dfd9f9..6b3b34fc00e 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml @@ -8,7 +8,7 @@ /** @var \Magento\Customer\Block\Account\Resetpassword $block */ ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getUrl('*/*/resetpasswordpost', ['_query' => ['id' => $block->getCustomerId(), 'token' => $block->getResetPasswordLinkToken()]]); ?>" +<form action="<?php echo $block->escapeUrl($block->getUrl('*/*/resetpasswordpost', ['_query' => ['id' => $block->getCustomerId(), 'token' => $block->getResetPasswordLinkToken()]])); ?>" method="post" <?php if ($block->isAutocompleteDisabled()) :?> autocomplete="off"<?php endif; ?> id="form-validate" @@ -19,8 +19,8 @@ <label class="label" for="password"><span><?php /* @escapeNotVerified */ echo __('New Password'); ?></span></label> <div class="control"> <input type="password" class="input-text" name="password" id="password" - data-password-min-length="<?php echo $block->escapeHtml($block->getMinimumPasswordLength()) ?>" - data-password-min-character-sets="<?php echo $block->escapeHtml($block->getRequiredCharacterClassesNumber()) ?>" + data-password-min-length="<?php echo $block->escapeHtmlAttr($block->getMinimumPasswordLength()) ?>" + data-password-min-character-sets="<?php echo $block->escapeHtmlAttr($block->getRequiredCharacterClassesNumber()) ?>" data-validate="{required:true, 'validate-customer-password':true}" autocomplete="off"> <div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite"> diff --git a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml index 373bec3601a..3a2bd0dd74a 100644 --- a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml @@ -9,7 +9,7 @@ ?> <script type="text/x-magento-init"> <?php - /* @escapeNotVerified */ echo $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([ + /* @noEscape */ echo $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([ '*' => ['Magento_Customer/js/customer-data' => [ 'sectionLoadUrl' => $block->getCustomerDataUrl('customer/section/load'), 'cookieLifeTime' => $block->getCookieLifeTime(), diff --git a/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml b/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml index 3cde7b1dade..d48fbff4e80 100644 --- a/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml @@ -9,7 +9,7 @@ ?> <script type="text/x-magento-init"> <?php - /* @escapeNotVerified */ echo $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([ + /* @noEscape */ echo $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([ '*' => ['Magento_Customer/js/section-config' => [ 'sections' => $block->getSections(), 'clientSideSections' => $block->getClientSideSections(), diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml index 4fa8cd6aeb7..3eaa230b684 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml @@ -35,12 +35,12 @@ NOTE: Regarding styles - if we leave it this way, we'll move it to boxes.css $fieldCssClass = 'field date field-' . $block->getHtmlId(); $fieldCssClass .= $block->isRequired() ? ' required' : ''; ?> -<div class="<?php /* @escapeNotVerified */ echo $fieldCssClass; ?>"> - <label class="label" for="<?php echo $block->getHtmlId()?>"><span><?php /* @escapeNotVerified */ echo $block->getLabel() ?></span></label> +<div class="<?php echo $block->escapeHtmlAttr($fieldCssClass); ?>"> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getHtmlId()) ?>"><span><?php echo $block->escapeHtml($block->getLabel()) ?></span></label> <div class="control customer-dob"> <?php echo $block->getFieldHtml(); ?> <?php if ($_message = $block->getAdditionalDescription()) : ?> - <div class="note"><?php /* @escapeNotVerified */ echo $_message; ?></div> + <div class="note"><?php echo $block->escapeHtml($_message); ?></div> <?php endif; ?> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml index 391bd20ee8c..3c766812be3 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml @@ -8,13 +8,13 @@ ?> <div class="field gender<?php if ($block->isRequired()) echo ' required' ?>"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('gender')?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> <div class="control"> - <select id="<?php /* @escapeNotVerified */ echo $block->getFieldId('gender')?>" name="<?php /* @escapeNotVerified */ echo $block->getFieldName('gender')?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?> <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?>> + <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?> <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?>> <?php $options = $block->getGenderOptions(); ?> <?php $value = $block->getGender();?> <?php foreach ($options as $option):?> - <option value="<?php /* @escapeNotVerified */ echo $option->getValue() ?>"<?php if ($option->getValue() == $value) echo ' selected="selected"' ?>><?php /* @escapeNotVerified */ echo __($option->getLabel()) ?></option> + <option value="<?php echo $block->escapeHtmlAttr($option->getValue()) ?>"<?php if ($option->getValue() == $value) echo ' selected="selected"' ?>><?php /* @escapeNotVerified */ echo __($option->getLabel()) ?></option> <?php endforeach;?> </select> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index f1f1416c2f4..d8758f0bc76 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -31,8 +31,8 @@ $suffix = $block->showSuffix(); ?> <?php if (($prefix || $middle || $suffix) && !$block->getNoWrap()): ?> -<div class="field required fullname <?php /* @escapeNotVerified */ echo $block->getContainerClassName() ?>"> - <label for="<?php /* @escapeNotVerified */ echo $block->getFieldId('firstname') ?>" class="label"> +<div class="field required fullname <?php echo $block->escapeHtmlAttr($block->getContainerClassName()) ?>"> + <label for="<?php echo $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>" class="label"> <span><?php /* @escapeNotVerified */ echo __('Name') ?></span> </label> <div class="control"> @@ -42,24 +42,24 @@ $suffix = $block->showSuffix(); <?php if ($prefix): ?> <div class="field field-name-prefix<?php if ($block->isPrefixRequired()) echo ' required' ?>"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('prefix') ?>"> - <span><?php /* @escapeNotVerified */ echo $block->getStoreLabel('prefix') ?></span> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>"> + <span><?php echo $block->escapeHtml($block->getStoreLabel('prefix')) ?></span> </label> <div class="control"> <?php if ($block->getPrefixOptions() === false): ?> - <input type="text" id="<?php /* @escapeNotVerified */ echo $block->getFieldId('prefix') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('prefix') ?>" - value="<?php echo $block->escapeHtml($block->getObject()->getPrefix()) ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('prefix') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('prefix') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getObject()->getPrefix()) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>> <?php else: ?> - <select id="<?php /* @escapeNotVerified */ echo $block->getFieldId('prefix') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('prefix') ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('prefix') ?>" - class="<?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('prefix') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > + <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>" + class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > <?php foreach ($block->getPrefixOptions() as $_option): ?> - <option value="<?php /* @escapeNotVerified */ echo $_option ?>"<?php if ($block->getObject()->getPrefix() == $_option): ?> selected="selected"<?php endif; ?>> + <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getPrefix() == $_option): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo __($_option) ?> </option> <?php endforeach; ?> @@ -69,67 +69,67 @@ $suffix = $block->showSuffix(); </div> <?php endif; ?> <div class="field field-name-firstname required"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('firstname') ?>"> - <span><?php /* @escapeNotVerified */ echo $block->getStoreLabel('firstname') ?></span> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>"> + <span><?php echo $block->escapeHtml($block->getStoreLabel('firstname')) ?></span> </label> <div class="control"> - <input type="text" id="<?php /* @escapeNotVerified */ echo $block->getFieldId('firstname') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('firstname') ?>" - value="<?php echo $block->escapeHtml($block->getObject()->getFirstname()) ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('firstname') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('firstname') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('firstname')) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getObject()->getFirstname()) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('firstname')) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('firstname')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> </div> </div> <?php if ($middle): ?> <?php $isMiddlenameRequired = $block->isMiddlenameRequired(); ?> <div class="field field-name-middlename<?php echo $isMiddlenameRequired ? ' required' : '' ?>"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('middlename') ?>"> - <span><?php /* @escapeNotVerified */ echo $block->getStoreLabel('middlename') ?></span> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('middlename')) ?>"> + <span><?php echo $block->escapeHtml($block->getStoreLabel('middlename')) ?></span> </label> <div class="control"> - <input type="text" id="<?php /* @escapeNotVerified */ echo $block->getFieldId('middlename') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('middlename') ?>" - value="<?php echo $block->escapeHtml($block->getObject()->getMiddlename()) ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('middlename') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('middlename') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php echo $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('middlename')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('middlename')) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getObject()->getMiddlename()) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('middlename')) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('middlename')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php echo $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>> </div> </div> <?php endif; ?> <div class="field field-name-lastname required"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('lastname') ?>"> - <span><?php /* @escapeNotVerified */ echo $block->getStoreLabel('lastname') ?></span> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('lastname')) ?>"> + <span><?php echo $block->escapeHtml($block->getStoreLabel('lastname')) ?></span> </label> <div class="control"> - <input type="text" id="<?php /* @escapeNotVerified */ echo $block->getFieldId('lastname') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('lastname') ?>" - value="<?php echo $block->escapeHtml($block->getObject()->getLastname()) ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('lastname') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('lastname') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('lastname')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('lastname')) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getObject()->getLastname()) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('lastname')) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('lastname')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> </div> </div> <?php if ($suffix): ?> <div class="field field-name-suffix<?php if ($block->isSuffixRequired()) echo ' required' ?>"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('suffix') ?>"> - <span><?php /* @escapeNotVerified */ echo $block->getStoreLabel('suffix') ?></span> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>"> + <span><?php echo $block->escapeHtml($block->getStoreLabel('suffix')) ?></span> </label> <div class="control"> <?php if ($block->getSuffixOptions() === false): ?> - <input type="text" id="<?php /* @escapeNotVerified */ echo $block->getFieldId('suffix') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('suffix') ?>" - value="<?php echo $block->escapeHtml($block->getObject()->getSuffix()) ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('suffix') ?>" - class="input-text <?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('suffix') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>" + value="<?php echo $block->escapeHtmlAttr($block->getObject()->getSuffix()) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>" + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php else: ?> - <select id="<?php /* @escapeNotVerified */ echo $block->getFieldId('suffix') ?>" - name="<?php /* @escapeNotVerified */ echo $block->getFieldName('suffix') ?>" - title="<?php /* @escapeNotVerified */ echo $block->getStoreLabel('suffix') ?>" - class="<?php /* @escapeNotVerified */ echo $block->getAttributeValidationClass('suffix') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> + <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>" + name="<?php echo $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>" + title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>" + class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php foreach ($block->getSuffixOptions() as $_option): ?> - <option value="<?php /* @escapeNotVerified */ echo $_option ?>"<?php if ($block->getObject()->getSuffix() == $_option): ?> selected="selected"<?php endif; ?>> + <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getSuffix() == $_option): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo __($_option) ?> </option> <?php endforeach; ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml index f9fadb3a4c2..b903ef47f20 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml @@ -8,8 +8,8 @@ ?> <div class="field taxvat<?php if ($block->isRequired()) echo ' required'; ?>"> - <label class="label" for="<?php /* @escapeNotVerified */ echo $block->getFieldId('taxvat')?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> + <label class="label" for="<?php echo $block->escapeHtml($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> <div class="control"> - <input type="text" id="<?php /* @escapeNotVerified */ echo $block->getFieldId('taxvat')?>" name="<?php /* @escapeNotVerified */ echo $block->getFieldName('taxvat')?>" value="<?php echo $block->escapeHtml($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat') ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtml($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtml($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> </div> </div> -- GitLab From 5f56edd4637886bf4390c188429cdde0bdf4c43e Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 1 Aug 2016 13:32:20 -0500 Subject: [PATCH 092/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../create/address/form/renderer/vat.phtml | 6 +++--- .../templates/system/config/validatevat.phtml | 8 ++++---- .../view/adminhtml/templates/tab/cart.phtml | 20 +++++++++---------- .../templates/tab/view/personal_info.phtml | 16 +++++++-------- .../adminhtml/templates/tab/view/sales.phtml | 18 ++++++++--------- .../account/authentication-popup.phtml | 6 +++--- .../templates/account/dashboard/address.phtml | 6 +++--- .../templates/account/dashboard/info.phtml | 6 +++--- .../account/link/authorization.phtml | 2 +- .../view/frontend/templates/form/login.phtml | 2 +- .../view/frontend/templates/logout.phtml | 2 +- .../view/frontend/templates/newcustomer.phtml | 2 +- 12 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml index 29d0d546282..845227fdb2d 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml @@ -19,11 +19,11 @@ $_validateButton = $block->getValidateButton(); <div class="hidden"><?php echo $_element->getElementHtml(); ?></div> <?php else: ?> <?php echo $_element->getLabelHtml(); ?> - <div class="admin__field-control <?php /* @escapeNotVerified */ echo $_element->hasValueClass() ? $_element->getValueClass() : 'value'; ?><?php echo $_class ? " {$_class}-value" : ''; ?>"> + <div class="admin__field-control <?php /* @noEscape */ echo $_element->hasValueClass() ? $_element->getValueClass() : 'value'; ?><?php echo $_class ? " {$_class}-value" : ''; ?>"> <?php echo $_element->getElementHtml(); ?> <?php if ($_note): ?> - <div class="admin__field-note<?php echo $_class ? " {$_class}-note" : ''; ?>" id="note_<?php /* @escapeNotVerified */ echo $_element->getId(); ?>"> - <span><?php /* @escapeNotVerified */ echo $_note; ?></span> + <div class="admin__field-note<?php echo $_class ? " {$_class}-note" : ''; ?>" id="note_<?php echo $block->escapeHtmlAttr($_element->getId()); ?>"> + <span><?php echo $block->escapeHtml($_note); ?></span> </div> <?php endif; ?> <div class="actions"> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index 0e0e1d7a49a..6caedc48e56 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -20,11 +20,11 @@ require(['prototype'], function(){ var validationMessage = $('validation_result'); params = { - country: $('<?php /* @escapeNotVerified */ echo $block->getMerchantCountryField(); ?>').value, - vat: $('<?php /* @escapeNotVerified */ echo $block->getMerchantVatNumberField(); ?>').value + country: $('<?php echo $block->escapeJs($block->getMerchantCountryField()); ?>').value, + vat: $('<?php echo $block->escapeJs($block->getMerchantVatNumberField()); ?>').value }; - new Ajax.Request('<?php /* @escapeNotVerified */ echo $block->getAjaxUrl() ?>', { + new Ajax.Request('<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>', { parameters: params, onSuccess: function(response) { var result = '<?php /* @escapeNotVerified */ echo __('Error during VAT Number verification.') ?>'; @@ -53,7 +53,7 @@ require(['prototype'], function(){ </script> <div class="actions actions-validate-vat"> <div id="validation_result" class="message-validation hidden"></div> - <button onclick="javascript:validateVat(); return false;" class="action-validate-vat" type="button" id="<?php echo $block->getHtmlId() ?>"> + <button onclick="javascript:validateVat(); return false;" class="action-validate-vat" type="button" id="<?php echo $block->escapeHtmlAttr($block->getHtmlId()) ?>"> <span><?php echo $block->escapeHtml($block->getButtonLabel()) ?></span> </button> </div> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index af042211d41..3cbc496cfca 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -12,7 +12,7 @@ <div class="content-header skip-header"> <table> <tr> - <td style="width:50%;"><h4><?php /* @escapeNotVerified */ echo $block->getCartHeader(); ?></h4></td> + <td style="width:50%;"><h4><?php echo $block->escapeHtml($block->getCartHeader()); ?></h4></td> </tr> </table> </div> @@ -29,19 +29,19 @@ require([ "Magento_Catalog/catalog/product/composite/configure" ], function(alert, confirm){ -<?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>cartControl = { +<?php echo $block->escapeJs($block->getJsObjectName()) ?>cartControl = { reload: function (params) { if (!params) { params = {}; } - <?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>.reloadParams = params; - <?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>.reload(); - <?php /* @escapeNotVerified */ echo $block->getJsObjectName() ?>.reloadParams = {}; + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = params; + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reload(); + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = {}; }, configureItem: function (itemId) { - productConfigure.setOnLoadIFrameCallback('<?php /* @escapeNotVerified */ echo $listType ?>', this.cbOnLoadIframe.bind(this)); - productConfigure.showItemConfiguration('<?php /* @escapeNotVerified */ echo $listType ?>', itemId); + productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($listType) ?>', this.cbOnLoadIframe.bind(this)); + productConfigure.showItemConfiguration('<?php echo $block->escapeJs($listType) ?>', itemId); return false; }, @@ -81,10 +81,10 @@ $params = [ ]; ?> productConfigure.addListType( - '<?php /* @escapeNotVerified */ echo $listType ?>', + '<?php echo $block->escapeJs($listType) ?>', { - urlFetch: '<?php /* @escapeNotVerified */ echo $block->getUrl('customer/cart_product_composite_cart/configure', $params) ?>', - urlConfirm: '<?php /* @escapeNotVerified */ echo $block->getUrl('customer/cart_product_composite_cart/update', $params) ?>' + urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/configure', $params)) ?>', + urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/update', $params)) ?>' } ); diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml index 8296584cc16..c3b723c59d1 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml @@ -26,39 +26,39 @@ $createDateStore = $block->getStoreCreateDate(); <?php echo $block->getChildHtml(); ?> <tr> <th><?php /* @escapeNotVerified */ echo __('Last Logged In:') ?></th> - <td><?php /* @escapeNotVerified */ echo $lastLoginDateAdmin ?> (<?php /* @escapeNotVerified */ echo $block->getCurrentStatus() ?>)</td> + <td><?php echo $block->escapeHtml($lastLoginDateAdmin) ?> (<?php echo $block->escapeHtml($block->getCurrentStatus()) ?>)</td> </tr> <?php if ($lastLoginDateAdmin != $lastLoginDateStore): ?> <tr> <th><?php /* @escapeNotVerified */ echo __('Last Logged In (%1):', $block->getStoreLastLoginDateTimezone()) ?></th> - <td><?php /* @escapeNotVerified */ echo $lastLoginDateStore ?> (<?php /* @escapeNotVerified */ echo $block->getCurrentStatus() ?>)</td> + <td><?php echo $block->escapeHtml($lastLoginDateStore) ?> (<?php echo $block->escapeHtml($block->getCurrentStatus()) ?>)</td> </tr> <?php endif; ?> <tr> <th><?php /* @escapeNotVerified */ echo __('Account Lock:') ?></th> - <td><?php /* @escapeNotVerified */ echo $block->getAccountLock() ?></td> + <td><?php echo $block->escapeHtml($block->getAccountLock()) ?></td> </tr> <tr> <th><?php /* @escapeNotVerified */ echo __('Confirmed email:') ?></th> - <td><?php /* @escapeNotVerified */ echo $block->getIsConfirmedStatus() ?></td> + <td><?php echo $block->escapeHtml($block->getIsConfirmedStatus()) ?></td> </tr> <tr> <th><?php /* @escapeNotVerified */ echo __('Account Created:') ?></th> - <td><?php /* @escapeNotVerified */ echo $createDateAdmin ?></td> + <td><?php echo $block->escapeHtml($createDateAdmin) ?></td> </tr> <?php if ($createDateAdmin != $createDateStore): ?> <tr> <th><?php /* @escapeNotVerified */ echo __('Account Created on (%1):', $block->getStoreCreateDateTimezone()) ?></th> - <td><?php /* @escapeNotVerified */ echo $createDateStore ?></td> + <td><?php echo $block->escapeHtml($createDateStore) ?></td> </tr> <?php endif; ?> <tr> <th><?php /* @escapeNotVerified */ echo __('Account Created in:') ?></th> - <td><?php /* @escapeNotVerified */ echo $block->getCreatedInStore() ?></td> + <td><?php echo $block->escapeHtml($block->getCreatedInStore()) ?></td> </tr> <tr> <th><?php /* @escapeNotVerified */ echo __('Customer Group:') ?></th> - <td><?php /* @escapeNotVerified */ echo $block->getGroupName() ?></td> + <td><?php echo $block->escapeHtml($block->getGroupName()) ?></td> </tr> </tbody> </table> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml index 618839a8aa3..08f999ca1a2 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml @@ -31,8 +31,8 @@ <tfoot> <tr> <td colspan="3"><strong><?php /* @escapeNotVerified */ echo __('All Store Views') ?></strong></td> - <td class="emph"><strong><?php /* @escapeNotVerified */ echo $block->formatCurrency($block->getTotals()->getBaseLifetime()) ?></strong></td> - <td class="emph last"><strong><?php /* @escapeNotVerified */ echo $block->formatCurrency($block->getTotals()->getAvgsale()) ?></strong></td> + <td class="emph"><strong><?php echo $block->escapeHtml($block->formatCurrency($block->getTotals()->getBaseLifetime())) ?></strong></td> + <td class="emph last"><strong><?php echo $block->escapeHtml($block->formatCurrency($block->getTotals()->getAvgsale())) ?></strong></td> </tr> </tfoot> <?php endif; ?> @@ -46,24 +46,24 @@ <?php foreach ($_stores as $_row): ?> <?php if (!$singleStoreMode): ?> <?php if ($_row->getStoreId() == 0): ?> - <td colspan="3"><?php /* @escapeNotVerified */ echo $_row->getStoreName() ?></td> + <td colspan="3"><?php echo $block->escapeHtml($_row->getStoreName()) ?></td> <?php else: ?> <tr<?php echo($_i++ % 2 ? ' class="even"' : '') ?>> <?php if (!$_websiteRow): ?> - <td rowspan="<?php /* @escapeNotVerified */ echo $block->getWebsiteCount($_websiteId) ?>"><?php /* @escapeNotVerified */ echo $_row->getWebsiteName() ?></td> + <td rowspan="<?php echo $block->escapeHtmlAttr($block->getWebsiteCount($_websiteId)) ?>"><?php echo $block->escapeHtml($_row->getWebsiteName()) ?></td> <?php $_websiteRow = true; ?> <?php endif; ?> <?php if (!$_groupRow): ?> - <td rowspan="<?php echo count($_stores) ?>"><?php /* @escapeNotVerified */ echo $_row->getGroupName() ?></td> + <td rowspan="<?php echo count($_stores) ?>"><?php echo $block->escapeHtml($_row->getGroupName()) ?></td> <?php $_groupRow = true; ?> <?php endif; ?> - <td><?php /* @escapeNotVerified */ echo $_row->getStoreName() ?></td> + <td><?php echo $block->escapeHtml($_row->getStoreName()) ?></td> <?php endif; ?> <?php else: ?> <tr> <?php endif; ?> - <td><?php /* @escapeNotVerified */ echo $block->formatCurrency($_row->getLifetime(), $_row->getWebsiteId()) ?></td> - <td><?php /* @escapeNotVerified */ echo $block->formatCurrency($_row->getAvgsale(), $_row->getWebsiteId()) ?></td> + <td><?php echo $block->escapeHtml($block->formatCurrency($_row->getLifetime(), $_row->getWebsiteId())) ?></td> + <td><?php echo $block->escapeHtml($block->formatCurrency($_row->getAvgsale(), $_row->getWebsiteId())) ?></td> </tr> <?php endforeach; ?> <?php endforeach; ?> @@ -71,7 +71,7 @@ </tbody> <?php else: ?> <tbody> - <tr class="hidden"><td colspan="<?php /* @escapeNotVerified */ echo !$singleStoreMode ? '5' : '2'; ?>"></td></tr> + <tr class="hidden"><td colspan="<?php /* @noEscape */ echo $singleStoreMode ? 2 : 5; ?>"></td></tr> </tbody> <?php endif; ?> </table> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index f7330686c54..0554f21447d 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -9,16 +9,16 @@ ?> <div id="authenticationPopup" data-bind="scope:'authenticationPopup'" style="display: none;"> <script> - window.authenticationPopup = <?php /* @escapeNotVerified */ echo \Zend_Json::encode($block->getConfig()); ?>; + window.authenticationPopup = <?php /* @noEscape */ echo \Zend_Json::encode($block->getConfig()); ?>; </script> <!-- ko template: getTemplate() --><!-- /ko --> <script type="text/x-magento-init"> { "#authenticationPopup": { - "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?> + "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> }, "*": { - "Magento_Ui/js/block-loader": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-1.gif'); ?>" + "Magento_Ui/js/block-loader": "<?php echo $bock->escapeUrl($block->getViewFileUrl('images/loader-1.gif')); ?>" } } </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml index 7bfd6c2b9b9..ed6f2a835cf 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml @@ -11,7 +11,7 @@ <div class="block block-dashboard-addresses"> <div class="block-title"> <strong><?php /* @escapeNotVerified */ echo __('Address Book') ?></strong> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getAddressBookUrl() ?>"><span><?php /* @escapeNotVerified */ echo __('Manage Addresses') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressBookUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Manage Addresses') ?></span></a> </div> <div class="block-content"> <div class="box box-billing-address"> @@ -24,7 +24,7 @@ </address> </div> <div class="box-actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getPrimaryBillingAddressEditUrl() ?>" data-ui-id="default-billing-edit-link"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getPrimaryBillingAddressEditUrl()) ?>" data-ui-id="default-billing-edit-link"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> </div> </div> <div class="box box-shipping-address"> @@ -37,7 +37,7 @@ </address> </div> <div class="box-actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getPrimaryShippingAddressEditUrl() ?>" data-ui-id="default-shipping-edit-link"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getPrimaryShippingAddressEditUrl()) ?>" data-ui-id="default-shipping-edit-link"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> </div> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml index f4f3a517404..7eb24b1ffe8 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml @@ -22,10 +22,10 @@ </p> </div> <div class="box-actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getUrl('customer/account/edit') ?>"> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('customer/account/edit')) ?>"> <span><?php /* @escapeNotVerified */ echo __('Edit') ?></span> </a> - <a href="<?php /* @escapeNotVerified */ echo $block->getChangePasswordUrl() ?>" class="action change-password"> + <a href="<?php echo $block->escapeUrl($block->getChangePasswordUrl()) ?>" class="action change-password"> <?php /* @escapeNotVerified */ echo __('Change Password') ?> </a> </div> @@ -47,7 +47,7 @@ <?php echo $block->getChildHtml('customer.account.dashboard.info.extra')?> </div> <div class="box-actions"> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getUrl('newsletter/manage') ?>"><span><?php /* @escapeNotVerified */ echo __('Edit') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('newsletter/manage')) ?>"><span><?php /* @escapeNotVerified */ echo __('Edit') ?></span></a> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml index edd44e34a02..7b71b564499 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml @@ -13,7 +13,7 @@ if ($block->isLoggedIn()) { } ?> <li class="authorization-link" data-label="<?php echo $block->escapeHtml(__('or')); ?>"> - <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes(); ?><?php /* @escapeNotVerified */ echo $dataPostParam; ?>> + <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes(); ?><?php /* @noEscape */ echo $dataPostParam; ?>> <?php echo $block->escapeHtml($block->getLabel()); ?> </a> </li> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index b24013b18b3..f1189bb861c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -38,7 +38,7 @@ <div class="field password required"> <label for="pass" class="label"><span><?php /* @escapeNotVerified */ echo __('Password') ?></span></label> <div class="control"> - <input name="login[password]" type="password" <?php if ($block->isAutocompleteDisabled()) :?> autocomplete="off"<?php endif; ?> class="input-text" id="pass" title="<?php /* @escapeNotVerified */ echo __('Password') ?>" data-validate="{required:true}"> + <input name="login[password]" type="password" <?php if ($block->isAutocompleteDisabled()): ?> autocomplete="off"<?php endif; ?> class="input-text" id="pass" title="<?php /* @escapeNotVerified */ echo __('Password') ?>" data-validate="{required:true}"> </div> </div> <?php echo $block->getChildHtml('form_additional_info'); ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/logout.phtml b/app/code/Magento/Customer/view/frontend/templates/logout.phtml index 7b2c22913be..089444ff078 100644 --- a/app/code/Magento/Customer/view/frontend/templates/logout.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/logout.phtml @@ -11,7 +11,7 @@ require([ "mage/mage" ], function($){ - $($.mage.redirect("<?php /* @escapeNotVerified */ echo $block->getUrl() ?>", "assign", 5000)); + $($.mage.redirect("<?php echo $block->escapeJs($block->getUrl()) ?>", "assign", 5000)); }); </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml index d107ebdb188..39d41e6b782 100644 --- a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml @@ -23,7 +23,7 @@ <p><?php /* @escapeNotVerified */ echo __('Creating an account has many benefits: check out faster, keep more than one address, track orders and more.') ?></p> <div class="actions-toolbar"> <div class="primary"> - <a href="<?php /* @escapeNotVerified */ echo $block->getCreateAccountUrl() ?>" class="action create primary"><span><?php /* @escapeNotVerified */ echo __('Create an Account') ?></span></a> + <a href="<?php echo $block->escapeUrl($block->getCreateAccountUrl()) ?>" class="action create primary"><span><?php /* @escapeNotVerified */ echo __('Create an Account') ?></span></a> </div> </div> </div> -- GitLab From f7e4059d539eb3c8b7af16187a89d9ece25c22b9 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 1 Aug 2016 14:02:49 -0500 Subject: [PATCH 093/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../Magento/Customer/view/frontend/templates/form/login.phtml | 4 ++-- lib/internal/Magento/Framework/Escaper.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index f1189bb861c..8f0713840e4 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -32,7 +32,7 @@ <div class="field email required"> <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input name="login[username]" value="<?php echo $block->escapeHtmlAttr($block->getUsername()) ?>" <?php if ($block->isAutocompleteDisabled()) :?> autocomplete="off"<?php endif; ?> id="email" type="email" class="input-text" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" data-validate="{required:true, 'validate-email':true}"> + <input name="login[username]" value="<?php echo $block->escapeHtmlAttr($block->getUsername()) ?>" <?php if ($block->isAutocompleteDisabled()): ?> autocomplete="off"<?php endif; ?> id="email" type="email" class="input-text" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" data-validate="{required:true, 'validate-email':true}"> </div> </div> <div class="field password required"> @@ -44,7 +44,7 @@ <?php echo $block->getChildHtml('form_additional_info'); ?> <div class="actions-toolbar"> <div class="primary"><button type="submit" class="action login primary" name="send" id="send2"><span><?php /* @escapeNotVerified */ echo __('Sign In') ?></span></button></div> - <div class="secondary"><a class="action remind" href="<?php echo $block->escapeHtmlAttr($block->getForgotPasswordUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Forgot Your Password?') ?></span></a></div> + <div class="secondary"><a class="action remind" href="<?php echo $block->escapeUrl($block->getForgotPasswordUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Forgot Your Password?') ?></span></a></div> </div> </fieldset> </form> diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 64566aea2d2..fe88e2b0792 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -54,7 +54,7 @@ class Escaper public function escapeHtmlAttr($string, $escapeSingleQuote = true) { if ($escapeSingleQuote) { - return $this->getEscaper()->escapeHtmlAttr($string); + return $this->getEscaper()->escapeHtmlAttr((string) $string); } return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false); } -- GitLab From 7e2d749efe33b464c9c756a2120ff215d8a82af2 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 1 Aug 2016 14:49:53 -0500 Subject: [PATCH 094/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../frontend/templates/account/link/authorization.phtml | 2 +- .../Customer/view/frontend/templates/address/edit.phtml | 7 ++++--- .../Customer/view/frontend/templates/form/register.phtml | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml index 7b71b564499..53fafbc3109 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml @@ -13,7 +13,7 @@ if ($block->isLoggedIn()) { } ?> <li class="authorization-link" data-label="<?php echo $block->escapeHtml(__('or')); ?>"> - <a <?php /* @escapeNotVerified */ echo $block->getLinkAttributes(); ?><?php /* @noEscape */ echo $dataPostParam; ?>> + <a <?php /* @noEscape */ echo $block->getLinkAttributes(); ?><?php /* @noEscape */ echo $dataPostParam; ?>> <?php echo $block->escapeHtml($block->getLabel()); ?> </a> </li> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index f8e65778b78..19ce756d993 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -80,14 +80,15 @@ <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?> <?php for ($_i = 1, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i < $_n; $_i++): ?> <div class="field additional"> - <label class="label" for="street_<?php /* @escapeNotVerified */ echo $_i+1 ?>"> + <label class="label" for="street_<?php echo $_i+1 ?>"> <span><?php /* @escapeNotVerified */ echo __('Street Address %1', $_i+1) ?></span> </label> <div class="control"> <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getStreetLine($_i + 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i + 1) ?>" - id="street_<?php /* @escapeNotVerified */ echo $_i + 1 ?>" <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> + id="street_<?php echo $_i + 1 ?>" + class="<?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> </div> <?php endfor; ?> @@ -217,7 +218,7 @@ "regionInputId": "#region", "postcodeId": "#zip", "form": "#form-validate", - "regionJson": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, + "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, "defaultRegion": "<?php echo $block->escapeHtmlAttr($block->getRegionId()) ?>", "countriesWithOptionalZip": <?php echo $block->escapeHtmlAttr($this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true)) ?> } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index 842febeec50..38ea3068076 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -60,7 +60,7 @@ <div class="field telephone"> <label for="telephone" class="label"><span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span></label> <div class="control"> - <input type="text" name="telephone" id="telephone" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getTelephone()) ?>" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" class="input-text <?php /* @escapeNotVerified */ echo $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone') ?>"> + <input type="text" name="telephone" id="telephone" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getTelephone()) ?>" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone')) ?>"> </div> </div> @@ -74,11 +74,11 @@ <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?> <?php for ($_i = 2, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i <= $_n; $_i++): ?> <div class="field additional"> - <label class="label" for="street_<?php /* @escapeNotVerified */ echo $_i ?>"> + <label class="label" for="street_<?php /* @noEscape */ echo $_i ?>"> <span><?php /* @escapeNotVerified */ echo __('Address') ?></span> </label> <div class="control"> - <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreetLine($_i - 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i) ?>" id="street_<?php /* @escapeNotVerified */ echo $_i ?>" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> + <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreetLine($_i - 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i) ?>" id="street_<?php /* @noEscape */ echo $_i ?>" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> </div> <?php endfor; ?> -- GitLab From e702a245b77b757e08bc446a2fc64b099d1170db Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 1 Aug 2016 13:33:04 -0500 Subject: [PATCH 095/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../templates/customer/edit/tab/wishlist.phtml | 5 +++-- .../view/frontend/templates/button/share.phtml | 1 + .../view/frontend/templates/button/tocart.phtml | 2 ++ .../view/frontend/templates/button/update.phtml | 2 ++ .../item/renderer/actions/move_to_wishlist.phtml | 3 ++- .../catalog/product/list/addto/wishlist.phtml | 3 ++- .../catalog/product/view/addto/wishlist.phtml | 7 ++++--- .../view/frontend/templates/email/items.phtml | 9 +++++---- .../frontend/templates/item/column/actions.phtml | 1 + .../frontend/templates/item/column/cart.phtml | 8 +++++--- .../frontend/templates/item/column/comment.phtml | 3 ++- .../frontend/templates/item/column/edit.phtml | 7 +++++-- .../frontend/templates/item/column/image.phtml | 7 +++++-- .../frontend/templates/item/column/name.phtml | 7 +++++-- .../frontend/templates/item/column/price.phtml | 6 ++++-- .../frontend/templates/item/column/remove.phtml | 4 ++-- .../frontend/templates/item/configure/addto.phtml | 8 ++++---- .../templates/item/configure/addto/wishlist.phtml | 7 ++++--- .../view/frontend/templates/item/list.phtml | 3 ++- .../Wishlist/view/frontend/templates/link.phtml | 1 + .../messages/addProductSuccessMessage.phtml | 3 ++- .../view/frontend/templates/options_list.phtml | 1 + .../view/frontend/templates/rss/email.phtml | 2 +- .../view/frontend/templates/rss/wishlist.phtml | 5 +++-- .../Wishlist/view/frontend/templates/shared.phtml | 15 ++++++++------- .../view/frontend/templates/sharing.phtml | 5 +++-- .../view/frontend/templates/sidebar.phtml | 5 +++-- .../Wishlist/view/frontend/templates/view.phtml | 9 +++++---- 28 files changed, 87 insertions(+), 52 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index 334401d8ec0..7f7120bc8b5 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -9,6 +9,7 @@ /** * @var $block \Magento\Framework\View\Element\Template */ + ?> <script> require([ @@ -65,8 +66,8 @@ productConfigure.addListType( 'wishlist', { - urlFetch: '<?php /* @escapeNotVerified */ echo $block->getUrl('customer/wishlist_product_composite_wishlist/configure') ?>', - urlConfirm: '<?php /* @escapeNotVerified */ echo $block->getUrl('customer/wishlist_product_composite_wishlist/update') ?>' + urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/configure')) ?>', + urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/update')) ?>' } ); //--> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml index 558835f70d7..fd0884337ee 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ + ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->getShared() < $block->getConfig()->getSharingEmailLimit()): ?> <button type="submit" name="save_and_share" title="<?php /* @noEscape */ echo __('Share Wish List') ?>" class="action share"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml index b177b14f3a1..c0f113ac5f0 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ + ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->isSalable()): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml index bc1fd87f9fa..8af9851095b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ + ?> <?php if ($block->getWishlist()->getItemsCount()): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml index e115b71ba84..3de61a566b3 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml @@ -7,10 +7,11 @@ // @codingStandardsIgnoreFile /** @var $block \Magento\Wishlist\Block\Cart\Item\Renderer\Actions\MoveToWishlist */ + ?> <?php if ($block->isAllowInCart() && $block->isProductVisibleInSiteVisibility()): ?> <a href="#" - data-post='<?php /* @escapeNotVerified */ echo $block->getMoveFromCartParams(); ?>' + data-post='<?php /* @noEscape */ echo $block->getMoveFromCartParams(); ?>' class="use-ajax action action-towishlist"> <span><?php /* @noEscape */ echo __('Move to Wishlist'); ?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index a618788dfd8..df483967d00 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -6,13 +6,14 @@ // @codingStandardsIgnoreFile /** @var $block Magento\Wishlist\Block\Catalog\Product\ProductList\Item\AddTo\Wishlist */ + ?> <?php if ($block->getWishlistHelper()->isAllow()): ?> <a href="#" class="action towishlist" title="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>" aria-label="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>" - data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' + data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' data-action="add-to-wishlist" role="button"> <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml index 1062df9eb44..f70dcafbe72 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml @@ -6,18 +6,19 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Catalog\Product\View\Addto\Wishlist */ +/** @var $block \Magento\Wishlist\Block\Catalog\Product\View\AddTo\Wishlist */ + ?> <?php if ($block->isWishListAllowed()) : ?> <a href="#" class="action towishlist" - data-post='<?php /* @escapeNotVerified */ echo $block->getWishlistParams(); ?>' + data-post='<?php /* @noEscape */ echo $block->getWishlistParams(); ?>' data-action="add-to-wishlist"><span><?php /* @noEscape */ echo __('Add to Wish List') ?></span></a> <?php endif; ?> <script type="text/x-magento-init"> { "body": { - "addToWishlist": <?php /* @escapeNotVerified */ echo $block->getWishlistOptionsJson() ?> + "addToWishlist": <?php /* @noEscape */ echo $block->getWishlistOptionsJson() ?> } } </script> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml index f5569316162..ed974197c16 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /* @var $block \Magento\Wishlist\Block\Share\Email\Items */ + ?> <?php $l = $block->getWishlistItemsCount() ?> <div> @@ -19,13 +20,13 @@ <?php $_product = $item->getProduct(); ?> <td class="col product"> <p> - <a href="<?= /* @escapeNotVerified */ $block->getProductUrl($_product) ?>"> - <?php echo $block->getImage($_product, 'product_small_image')->toHtml(); ?> + <a href="<?= $block->escapeUrl($block->getProductUrl($_product)) ?>"> + <?php echo $block->escapeHtml($block->getImage($_product, 'product_small_image')->toHtml()); ?> </a> </p> <p> - <a href="<?= /* @escapeNotVerified */ $block->getProductUrl($_product) ?>"> + <a href="<?= $block->escapeUrl($block->getProductUrl($_product)) ?>"> <strong><?= $block->escapeHtml($_product->getName()) ?></strong> </a> </p> @@ -36,7 +37,7 @@ </p> <?php endif; ?> <p> - <a href="<?= /* @escapeNotVerified */ $block->getProductUrl($_product) ?>"> + <a href="<?= $block->escapeUrl($block->getProductUrl($_product)) ?>"> <?= /* @noEscape */ __('View Product') ?> </a> </p> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index f03b5ec3a29..7fb68d570cf 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -8,6 +8,7 @@ /** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ /* @var \Magento\Wishlist\Model\Item $item */ + ?> <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> 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 da6f4f86917..d3fabc1cdf5 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 @@ -6,10 +6,12 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart */ -/* @var \Magento\Wishlist\Model\Item $item */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart */ + +/** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); + ?> <?php foreach ($block->getChildNames() as $childName): ?> <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false); ?> @@ -28,7 +30,7 @@ $product = $item->getProduct(); <?php if ($product->isSaleable()): ?> <div class="product-item-actions"> <div class="actions-primary"> - <button type="button" data-role="tocart" data-post='<?php /* @escapeNotVerified */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtml($item->getId())?>" class="action tocart primary"> + <button type="button" data-role="tocart" data-post='<?php /* @noEscape */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtml($item->getId())?>" class="action tocart primary"> <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> </button> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index 86d13cf7bf6..4ed780c1c7d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -7,9 +7,10 @@ // @codingStandardsIgnoreFile /* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ -/* @var \Magento\Wishlist\Model\Item $item */ +/* @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); + ?> <div class="field comment-box"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index ac33424138a..b0901c86876 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -6,13 +6,16 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Model\Item $item */ +/** @var $block \Magento\Wishlist\Block\AbstractBlock */ + +/** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); + ?> <?php if ($product->isVisibleInSiteVisibility()): ?> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getItemConfigureUrl($item) ?>"> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getItemConfigureUrl($item)) ?>"> <span><?php /* @noEscape */ echo __('Edit') ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml index 77a6122499c..703dad67ec7 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml @@ -6,10 +6,13 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Model\Item $item */ +/** @var $block \Magento\Wishlist\Block\AbstractBlock */ + +/** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); + ?> -<a class="product-item-photo" href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> +<a class="product-item-photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> <?php echo $block->getImage($product, 'wishlist_thumbnail')->toHtml(); ?> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml index 5a8cf4ba5b6..8b06cacec5e 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml @@ -6,12 +6,15 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Model\Item $item */ +/** @var $block \Magento\Wishlist\Block\AbstractBlock */ + +/** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); + ?> <strong class="product-item-name"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>" class="product-item-link"> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>" class="product-item-link"> <?php echo $block->escapeHtml($product->getName()) ?> </a> </strong> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml index b12d3265fff..b207a42a156 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml @@ -6,9 +6,11 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Model\Item $item */ +/** @var $block \Magento\Wishlist\Block\AbstractBlock */ +/** @var \Magento\Wishlist\Model\Item $item */ + ?> <?php foreach ($block->getChildNames() as $childName): ?> - <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false); ?> + <?php echo $block->escapeHtml($block->getLayout()->renderElement($childName, false)); ?> <?php endforeach;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index cf803bbad06..bd5690fe4c5 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -6,10 +6,10 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ +/* @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove */ ?> -<a href="#" data-role="remove" data-post-remove='<?php /* @escapeNotVerified */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @noEscape */ echo __('Remove Item') ?>" class="btn-remove action delete"> +<a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @noEscape */ echo __('Remove Item') ?>" class="btn-remove action delete"> <span><?php /* @noEscape */ echo __('Remove item');?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml index 3333c68561f..f91e4e235e0 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml @@ -6,20 +6,20 @@ // @codingStandardsIgnoreFile -/* @var \Magento\RequisitionList\Block\Catalog\Product\View\Addto\Requisition $block */ +/** @var $block \Magento\Wishlist\Block\Item\configure */ ?> <div class="product-addto-links" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <?php $_product = $block->getProduct(); ?> <?php $_compareUrl = $this->helper('Magento\Catalog\Helper\Product\Compare')->getAddUrl($_product); ?> <?php if ($_compareUrl) : ?> - <a href="<?php /* @escapeNotVerified */ echo $_compareUrl ?>" class="action tocompare"> + <a href="<?php echo $block->escapeUrl($_compareUrl) ?>" class="action tocompare"> <span><?php /* @noEscape */ echo __('Add to Compare') ?></span> </a> <?php endif; ?> @@ -27,7 +27,7 @@ <script type="text/x-magento-init"> { "body": { - "addToWishlist": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> + "addToWishlist": <?php /* @noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml index f757672f931..dd209311ed5 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml @@ -6,17 +6,18 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Catalog\Product\View\Addto\Wishlist */ +/** @var $block \Magento\Wishlist\Block\Item\Configure */ + ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <script type="text/x-magento-init"> { "body": { - "addToWishlist": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> + "addToWishlist": <?php /* @noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml index 563e85778f9..46856248730 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml @@ -8,8 +8,9 @@ ?> <?php -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Items $block */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Items */ $columns = $block->getColumns(); + ?> <div class="products-grid wishlist"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/link.phtml b/app/code/Magento/Wishlist/view/frontend/templates/link.phtml index f00901afb05..d4867e94404 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/link.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/link.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /* @var $block \Magento\Wishlist\Block\Link */ + ?> <li class="link wishlist" data-bind="scope: 'wishlist'"> <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>><?php echo $block->escapeHtml($block->getLabel()) ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml index 52e6ddd1c1f..6c20828f4d9 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml @@ -5,6 +5,7 @@ */ /** @var \Magento\Framework\View\Element\Template $block */ + ?> -<?php echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); +<?php /* @escapeVerified */ echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php /* @escapeVerified */ echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index b9d83593fdc..68f52c7ca81 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /* @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Options */ + ?> <?php $options = $block->getOptionList(); ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml index f7290fe43f1..54eac70c29b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml @@ -12,6 +12,6 @@ <p style="font-size:12px; line-height:16px; margin:0 0 16px;"> <?php echo __("RSS link to %1's wishlist", $block->escapeHtml($this->helper('Magento\Wishlist\Helper\Data')->getCustomerName())) ?> <br /> - <a href="<?php /* @escapeNotVerified */ echo $block->getLink(); ?>"><?php /* @escapeNotVerified */ echo $block->getLink(); ?></a> + <a href="<?php echo $block->escapeUrl($block->getLink()); ?>"><?php echo $block->escapeUrl($block->getLink()); ?></a> </p> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml index c44b3ea13dc..7bffc0f5512 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml @@ -6,10 +6,11 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Rss\Link */ +/** @var $block \Magento\Wishlist\Block\Rss\Link */ + ?> <?php if ($block->isRssAllowed() && $block->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?> - <a href="<?php /* @escapeNotVerified */ echo $block->getLink(); ?>" class="action rss wishlist"> + <a href="<?php echo $block->escapeUrl($block->getLink()); ?>" class="action rss wishlist"> <span><?php /* @noEscape */ echo __('RSS Feed') ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index e7d1bc86825..ac90dfb31af 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -6,11 +6,12 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Share\Wishlist */ +/** @var $block \Magento\Wishlist\Block\Share\Wishlist */ + ?> <?php if ($block->hasWishlistItems()): ?> - <form class="form shared wishlist" action="<?php /* @escapeNotVerified */ echo $block->getUrl('wishlist/index/update') ?>" method="post"> + <form class="form shared wishlist" action="<?php echo $block->escapeUrl($block->getUrl('wishlist/index/update')) ?>" method="post"> <div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> <caption class="table-caption"><?php /* @noEscape */ echo __('Wish List'); ?></caption> @@ -29,11 +30,11 @@ ?> <tr> <td data-th="<?php echo $block->escapeHtml(__('Product')) ?>" class="col product"> - <a class="product photo" href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> + <a class="product photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> <?php echo $block->getImage($product, 'customer_shared_wishlist')->toHtml(); ?> </a> <strong class="product name"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>"> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>"> <?php echo $block->escapeHtml($product->getName()) ?> </a> </strong> @@ -53,13 +54,13 @@ <?php if ($isVisibleProduct): ?> <button type="button" title="<?php /* @noEscape */ echo __('Add to Cart') ?>" - data-post='<?php /* @escapeNotVerified */ echo $block->getSharedItemAddToCartUrl($item); ?>' + data-post='<?php /* @noEscape */ echo $block->getSharedItemAddToCartUrl($item); ?>' class="action tocart"> <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> </button> <?php endif ?> <?php endif; ?> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> </a> </td> @@ -74,7 +75,7 @@ <div class="primary"> <button type="button" title="<?php /* @noEscape */ echo __('Add All to Cart') ?>" - data-post='<?php /* @escapeNotVerified */ echo $block->getSharedAddAllToCartUrl(); ?>' + data-post='<?php echo $block->escapeUrl($block->getSharedAddAllToCartUrl()); ?>' class="action tocart primary"> <span><?php /* @noEscape */ echo __('Add All to Cart') ?></span> </button> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index ae32b8c581a..d2c7619a826 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -7,9 +7,10 @@ // @codingStandardsIgnoreFile /** @var $block \Magento\Wishlist\Block\Customer\Sharing */ + ?> <form class="form wishlist share" - action="<?php /* @escapeNotVerified */ echo $block->getSendUrl() ?>" + action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" id="form-validate" method="post" data-hasrequired="<?php /* @noEscape */ echo __('* Required Fields') ?>" @@ -47,7 +48,7 @@ </button> </div> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl(); ?>"><span><?php /* @noEscape */ echo __('Back')?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"><span><?php /* @noEscape */ echo __('Back')?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml index c333deb1923..465662c2bc1 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml @@ -6,7 +6,8 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Customer\Sidebar */ +/** @var $block \Magento\Wishlist\Block\Customer\Sidebar */ + ?> <?php $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); @@ -61,7 +62,7 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <div class="actions-toolbar no-display" data-bind="css: {'no-display': null}"> <div class="primary"> <a class="action details" - href="<?php /* @escapeNotVerified */ echo $this->helper('Magento\Wishlist\Helper\Data')->getListUrl() ?>" + href="<?php echo $block->escapeUrl($this->helper('Magento\Wishlist\Helper\Data')->getListUrl()) ?>" title="<?php /* @noEscape */ echo __('Go to Wish List') ?>"><span><?php /* @noEscape */ echo __('Go to Wish List') ?></span></a> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml index 5f2eef48307..3ef71a66825 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml @@ -6,17 +6,18 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Customer\Wishlist */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist */ + ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <?php echo($block->getChildHtml('wishlist.rss.link'));?> <form class="form-wishlist-items" id="wishlist-view-form" data-mage-init='{"wishlist":{ - "addToCartUrl":<?php /* @escapeNotVerified */ echo $block->getItemAddToCartParams("%item%");?>, - "addAllToCartUrl":<?php /* @escapeNotVerified */ echo $block->getAddAllToCartParams(); ?>, + "addToCartUrl":<?php /* @noEscape */ echo $block->getItemAddToCartParams("%item%");?>, + "addAllToCartUrl":<?php /* @noEscape */ echo $block->getAddAllToCartParams(); ?>, "commentString":""}, - "validation": {}}' action="<?php /* @escapeNotVerified */ echo $block->getUrl('wishlist/index/update', ['wishlist_id' => $block->getWishlistInstance()->getId()]) ?>" method="post"> + "validation": {}}' action="<?php echo $block->escapeUrl($block->getUrl('wishlist/index/update', ['wishlist_id' => $block->getWishlistInstance()->getId()])) ?>" method="post"> <?php echo $block->getChildHtml('top'); ?> <?php if ($block->hasWishlistItems()): ?> <?php echo $block->getBlockHtml('formkey');?> -- GitLab From 5ec5e5e6eb28ae4ed9d60f570ac8ee4258a33bf6 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Mon, 1 Aug 2016 15:26:58 -0500 Subject: [PATCH 096/838] MAGETWO-55921: Eliminate @escapeNotVerified in Newsletter Module - Eliminated all escapeNotVerified that are not translation. --- .../adminhtml/templates/preview/store.phtml | 6 +++--- .../view/adminhtml/templates/queue/edit.phtml | 6 +++--- .../adminhtml/templates/subscriber/list.phtml | 2 +- .../adminhtml/templates/template/edit.phtml | 18 +++++++++--------- .../view/frontend/templates/subscribe.phtml | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml index 1c2d53b94a5..7383a8ece33 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml @@ -23,13 +23,13 @@ <?php foreach ($block->getStores($group) as $store): ?> <?php if ($showWebsite == false): ?> <?php $showWebsite = true; ?> - <optgroup label="<?php /* @escapeNotVerified */ echo $website->getName() ?>"></optgroup> + <optgroup label="<?php echo $block->escapeHtmlAttr($website->getName()) ?>"></optgroup> <?php endif; ?> <?php if ($showGroup == false): ?> <?php $showGroup = true; ?> - <optgroup label=" <?php /* @escapeNotVerified */ echo $group->getName() ?>"> + <optgroup label=" <?php echo $block->escapeHtmlAttr($group->getName()) ?>"> <?php endif; ?> - <option value="<?php /* @escapeNotVerified */ echo $store->getId() ?>"<?php if ($block->getStoreId() == $store->getId()): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo $store->getName() ?></option> + <option value="<?php echo $block->escapeHtmlAttr($store->getId()) ?>"<?php if ($block->getStoreId() == $store->getId()): ?> selected="selected"<?php endif; ?>> <?php echo $block->escapeHtml($store->getName()) ?></option> <?php endforeach; ?> <?php if ($showGroup): ?> </optgroup> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml index b7f36f51264..cc5df715b14 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml @@ -20,14 +20,14 @@ <?php endif ?> </div> -<form action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" id="queue_edit_form"> +<form action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" method="post" id="queue_edit_form"> <?php echo $block->getBlockHtml('formkey')?> <?php echo $block->getChildHtml('form') ?> </form> -<form action="<?php /* @escapeNotVerified */ echo $block->getPreviewUrl() ?>" method="post" id="newsletter_queue_preview_form" target="_blank"> +<form action="<?php echo $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="newsletter_queue_preview_form" target="_blank"> <?php echo $block->getBlockHtml('formkey')?> <div class="no-display"> - <input type="hidden" id="preview_type" name="type" value="<?php /* @escapeNotVerified */ echo $block->getIsTextType() ? 1 : 2 ?>" /> + <input type="hidden" id="preview_type" name="type" value="<?php /* @noEscape */ echo $block->getIsTextType() ? 1 : 2 ?>" /> <input type="hidden" id="preview_text" name="text" value="" /> <input type="hidden" id="preview_styles" name="styles" value="" /> <input type="hidden" id="preview_id" name="id" value="" /> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml index b4bdb67b277..9f372679d32 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml @@ -12,7 +12,7 @@ <div class="form-buttons"> <select id="queueList" name="queue"> <?php foreach ($block->getQueueAsOptions() as $_queue): ?> - <option value="<?php /* @escapeNotVerified */ echo $_queue['value'] ?>"><?php /* @escapeNotVerified */ echo $_queue['label'] ?> #<?php /* @escapeNotVerified */ echo $_queue['value'] ?></option> + <option value="<?php echo $block->escapeHtmlAttr($_queue['value']) ?>"><?php echo $block->escapeHtml($_queue['label']) ?> #<?php echo $block->escapeHtml($_queue['value']) ?></option> <?php endforeach; ?> </select> <button type="button" class="scalable" onclick="subscriberController.addToQueue();"><span><span><span><?php /* @escapeNotVerified */ echo __('Add to Queue'); ?></span></span></span></button> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index 91db6c13eae..59445f029b1 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -10,18 +10,18 @@ use Magento\Framework\App\TemplateTypesInterface; /* @var $block \Magento\Newsletter\Block\Adminhtml\Template\Edit */ ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" id="newsletter_template_edit_form"> +<form action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" method="post" id="newsletter_template_edit_form"> <?php echo $block->getBlockHtml('formkey')?> <div class="no-display"> <input type="hidden" id="change_flag_element" name="_change_type_flag" value="" /> - <input type="hidden" id="save_as_flag" name="_save_as_flag" value="<?php /* @escapeNotVerified */ echo $block->getSaveAsFlag() ?>" /> + <input type="hidden" id="save_as_flag" name="_save_as_flag" value="<?php echo $block->escapeHtmlAttr($block->getSaveAsFlag()) ?>" /> </div> - <?php /* @escapeNotVerified */ echo $block->getForm() ?> + <?php echo $block->escapeHtml($block->getForm()) ?> </form> -<form action="<?php /* @escapeNotVerified */ echo $block->getPreviewUrl() ?>" method="post" id="newsletter_template_preview_form" target="_blank"> +<form action="<?php echo $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="newsletter_template_preview_form" target="_blank"> <?php echo $block->getBlockHtml('formkey')?> <div class="no-display"> - <input type="hidden" id="preview_type" name="type" value="<?php /* @escapeNotVerified */ echo $block->isTextType() ? 1 : 2 ?>" /> + <input type="hidden" id="preview_type" name="type" value="<?php /* @noEscape */ echo $block->isTextType() ? 1 : 2 ?>" /> <input type="hidden" id="preview_text" name="text" value="" /> <input type="hidden" id="preview_styles" name="styles" value="" /> <input type="hidden" id="preview_id" name="id" value="" /> @@ -175,9 +175,9 @@ require([ preview: function() { if (this.typeChange) { - $('preview_type').value = <?php /* @escapeNotVerified */ echo TemplateTypesInterface::TYPE_TEXT ?>; + $('preview_type').value = <?php echo $block->escapeJs(TemplateTypesInterface::TYPE_TEXT) ?>; } else { - $('preview_type').value = <?php /* @escapeNotVerified */ echo $block->getTemplateType() ?>; + $('preview_type').value = <?php echo $block->escapeJs($block->getTemplateType()) ?>; } if (this.isEditor() && tinyMCE.get(this.id)) { tinyMCE.triggerSave(); @@ -202,7 +202,7 @@ require([ content: "<?php /* @escapeNotVerified */ echo __('Are you sure you want to delete this template?') ?>", actions: { confirm: function() { - window.location.href = '<?php /* @escapeNotVerified */ echo $block->getDeleteUrl() ?>'; + window.location.href = '<?php echo $block->escapeUrl($block->getDeleteUrl()) ?>'; } } }); @@ -218,7 +218,7 @@ require([ }; templateControl.init(); - templateControl.templateName = "<?php /* @escapeNotVerified */ echo $block->getJsTemplateName() ?>"; + templateControl.templateName = "<?php echo $block->escapeJs($block->getJsTemplateName()) ?>"; //]]> }); diff --git a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml index a8b63a30572..ec36fa204fd 100644 --- a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml +++ b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml @@ -12,7 +12,7 @@ <div class="content"> <form class="form subscribe" novalidate - action="<?php /* @escapeNotVerified */ echo $block->getFormActionUrl() ?>" + action="<?php echo $block->escapeUrl($block->getFormActionUrl()) ?>" method="post" data-mage-init='{"validation": {"errorClass": "mage-error"}}' id="newsletter-validate-detail"> -- GitLab From 9eacbc10065f9ba6c01621ae1f4f8046e6a5ce7f Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Mon, 1 Aug 2016 15:31:06 -0500 Subject: [PATCH 097/838] MAGETWO-55922: Eliminate @escapeNotVerified in ProductAlert Module - Eliminated all escapeNotVerified that are not translation. --- .../ProductAlert/view/frontend/templates/product/view.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml b/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml index de9137be0b0..dd65bb07a60 100644 --- a/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml +++ b/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml @@ -6,7 +6,7 @@ ?> <?php /* @var $block \Magento\ProductAlert\Block\Product\View */?> <div class="product alert <?php echo $block->getHtmlClass() ?>"> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getPostAction(); ?>' + <a href="#" data-post='<?php echo $block->escapeUrl($block->getPostAction()); ?>' title="<?php echo $block->escapeHtml(__($block->getSignupLabel())); ?>" class="action alert"> <?php echo $block->escapeHtml(__($block->getSignupLabel())); ?> </a> -- GitLab From c7ae702a90517590ef6d9c6f51f2dc7275b519dc Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 1 Aug 2016 16:39:02 -0500 Subject: [PATCH 098/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../Magento/Customer/view/frontend/templates/address/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index 19ce756d993..e0fdca76852 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -213,7 +213,7 @@ }, "#country": { "regionUpdater": { - "optionalRegionAllowed": <?php /* @noEscape */ $block->getConfig('general/region/display_all') ? 'true' : 'false'; ?>, + "optionalRegionAllowed": <?php /* @noEscape */ echo $block->getConfig('general/region/display_all') ? 'true' : 'false'; ?>, "regionListId": "#region_id", "regionInputId": "#region", "postcodeId": "#zip", -- GitLab From 8cda0dd1db3479e07db86f232b64028d38e7d6bc Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 1 Aug 2016 16:56:49 -0500 Subject: [PATCH 099/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../view/adminhtml/templates/default.phtml | 14 +++++++------- .../view/frontend/templates/default.phtml | 18 +++++++++--------- .../Contact/view/frontend/templates/form.phtml | 3 ++- .../view/frontend/templates/html/notices.phtml | 8 ++++---- .../frontend/templates/require_cookie.phtml | 3 ++- .../view/frontend/templates/remember_me.phtml | 5 +++-- .../Rss/view/frontend/templates/feeds.phtml | 7 ++++--- .../view/frontend/templates/send.phtml | 4 ++-- 8 files changed, 33 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index 3ec8f108bc1..da3ec0a62ee 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -19,7 +19,7 @@ id="captcha" class="admin__control-text" type="text" - name="<?php /* @escapeNotVerified */ echo \Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE ?>[<?php /* @escapeNotVerified */ echo $block->getFormId()?>]" + name="<?php echo $block->escapeHtml(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtml($block->getFormId())?>]" data-validate="{required:true}"/> <?php if ($captcha->isCaseSensitive()) :?> <div class="admin__field-note"> @@ -32,19 +32,19 @@ <img id="captcha-reload" class="captcha-reload" - src="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Captcha::reload.png') ?>" + src="<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Captcha::reload.png')) ?>" alt="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"/> <img - id="<?php /* @escapeNotVerified */ echo $block->getFormId() ?>" - width="<?php /* @escapeNotVerified */ echo $block->getImgWidth() ?>" - height="<?php /* @escapeNotVerified */ echo $block->getImgHeight() ?>" - src="<?php /* @escapeNotVerified */ echo $captcha->getImgSrc() ?>" /> + id="<?php echo $block->escapeHtml($block->getFormId()) ?>" + width="<?php echo (int) $block->getImgWidth() ?>" + height="<?php echo (int) $block->getImgHeight() ?>" + src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>" /> </div> <script> require(["prototype", "mage/captcha"], function(){ //<![CDATA[ - var captcha = new Captcha('<?php /* @escapeNotVerified */ echo $block->getRefreshUrl() ?>', '<?php /* @escapeNotVerified */ echo $block->getFormId() ?>'); + var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeHtml($block->getFormId()) ?>'); $('captcha-reload').observe('click', function () { captcha.refresh(this); diff --git a/app/code/Magento/Captcha/view/frontend/templates/default.phtml b/app/code/Magento/Captcha/view/frontend/templates/default.phtml index d97d2922c02..0739623dfa3 100644 --- a/app/code/Magento/Captcha/view/frontend/templates/default.phtml +++ b/app/code/Magento/Captcha/view/frontend/templates/default.phtml @@ -10,19 +10,19 @@ <?php /* @var $captcha \Magento\Captcha\Model\DefaultModel */ ?> <?php /* @var $block \Magento\Captcha\Block\Captcha\DefaultCaptcha */ ?> <?php $captcha = $block->getCaptchaModel() ?> -<div class="field captcha required" role="<?php /* @escapeNotVerified */ echo $block->getFormId()?>"> - <label for="captcha_<?php /* @escapeNotVerified */ echo $block->getFormId() ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Please type the letters below')?></span></label> +<div class="field captcha required" role="<?php echo $block->escapeHtml($block->getFormId())?>"> + <label for="captcha_<?php echo $block->escapeHtml($block->getFormId()) ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Please type the letters below')?></span></label> <div class="control captcha"> - <input name="<?php /* @escapeNotVerified */ echo \Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE ?>[<?php /* @escapeNotVerified */ echo $block->getFormId()?>]" type="text" class="input-text required-entry" data-validate="{required:true}" id="captcha_<?php /* @escapeNotVerified */ echo $block->getFormId() ?>" /> + <input name="<?php echo $block->escapeHtml(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtml($block->getFormId())?>]" type="text" class="input-text required-entry" data-validate="{required:true}" id="captcha_<?php echo $block->escapeHtml($block->getFormId()) ?>" /> <div class="nested"> <div class="field captcha no-label" - data-captcha="<?php /* @escapeNotVerified */ echo $block->getFormId()?>" - id="captcha-container-<?php /* @escapeNotVerified */ echo $block->getFormId()?>" - data-mage-init='{"captcha":{"url": "<?php /* @escapeNotVerified */ echo $block->getRefreshUrl()?>", - "imageLoader": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-2.gif') ?>", - "type": "<?php /* @escapeNotVerified */ echo $block->getFormId() ?>"}}'> + data-captcha="<?php echo $block->escapeHtml($block->getFormId())?>" + id="captcha-container-<?php echo $block->escapeHtml($block->getFormId())?>" + data-mage-init='{"captcha":{"url": "<?php echo $block->escapeUrl($block->getRefreshUrl())?>", + "imageLoader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-2.gif')) ?>", + "type": "<?php echo $block->escapeHtml($block->getFormId()) ?>"}}'> <div class="control captcha-image"> - <img alt="<?php /* @escapeNotVerified */ echo __('Please type the letters below')?>" class="captcha-img" height="<?php /* @escapeNotVerified */ echo $block->getImgHeight() ?>" src="<?php /* @escapeNotVerified */ echo $captcha->getImgSrc() ?>"/> + <img alt="<?php /* @escapeNotVerified */ echo __('Please type the letters below')?>" class="captcha-img" height="<?php echo (int) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>"/> <button type="button" class="action reload captcha-reload" title="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"><span><?php /* @escapeNotVerified */ echo __('Reload captcha') ?></span></button> </div> </div> diff --git a/app/code/Magento/Contact/view/frontend/templates/form.phtml b/app/code/Magento/Contact/view/frontend/templates/form.phtml index 63cf1929e38..aa8d6975389 100644 --- a/app/code/Magento/Contact/view/frontend/templates/form.phtml +++ b/app/code/Magento/Contact/view/frontend/templates/form.phtml @@ -7,8 +7,9 @@ // @codingStandardsIgnoreFile ?> +<?php /** @var $block \Magento\Contact\Block\ContactForm */ ?> <form class="form contact" - action="<?php /* @escapeNotVerified */ echo $block->getFormAction(); ?>" + action="<?php echo $block->escapeUrl($block->getFormAction()); ?>" id="contact-form" method="post" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 0ef6e395c03..63d6e253836 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -27,10 +27,10 @@ "#notice-cookie-block": { "cookieNotices": { "cookieAllowButtonSelector": "#btn-cookie-allow", - "cookieName": "<?php /* @escapeNotVerified */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", - "cookieValue": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, - "cookieLifetime": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>, - "noCookiesUrl": "<?php /* @escapeNotVerified */ echo $block->getUrl('cookie/index/noCookies') ?>" + "cookieName": "<?php echo $block->escapeHtml(\Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE) ?>", + "cookieValue": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, + "cookieLifetime": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>, + "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" } } } diff --git a/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml b/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml index dd3f56da745..5d8c2e7224d 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml @@ -3,12 +3,13 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + ?> <?php /** @var \Magento\Cookie\Block\RequireCookie $block */ ?> <script type="text/x-magento-init"> { "body": { - "requireCookie": <?php /* @escapeNotVerified */ echo $block->getScriptOptions(); ?> + "requireCookie": <?php /* @noEscape */ echo $block->getScriptOptions(); ?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml index c233b54e129..c7730933508 100644 --- a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml +++ b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml @@ -13,11 +13,12 @@ * * @var $block \Magento\Persistent\Block\Form\Remember */ + ?> <div id="remember-me-box" class="field choice persistent"> <?php $rememberMeId = 'remember_me' . $block->getRandomString(10); ?> - <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php /* @escapeNotVerified */ echo $rememberMeId; ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> - <label for="<?php /* @escapeNotVerified */ echo $rememberMeId; ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> + <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $block->escapeHtml($rememberMeId); ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> + <label for="<?php echo $block->escapeHtml($rememberMeId); ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> <span class="tooltip wrapper"> <a class="link tooltip toggle" href="#"><?php /* @escapeNotVerified */ echo __('What\'s this?') ?></a> <span class="tooltip content"> diff --git a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml index 81ac6fd8032..7c7c3a48390 100644 --- a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml +++ b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile ?> +<?php /** @var $block \Magento\Rss\Block\Feeds */ ?> <table class="data table rss"> <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Feed'); ?></caption> <tbody> @@ -16,16 +17,16 @@ <tr> <td class="col feed"><?php echo $block->escapeHtml($feed['label']) ?></td> <td class="col action"> - <a href="<?php /* @escapeNotVerified */ echo $feed['link'] ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> + <a href="<?php echo $block->escapeUrl($feed['link']) ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> </td> </tr> <?php else: ?> - <th colspan="2" scope="col"><?php /* @escapeNotVerified */ echo $feed['group'] ?></th> + <th colspan="2" scope="col"><?php echo $block->escapeHtml($feed['group']) ?></th> <?php foreach ($feed['feeds'] as $item) :?> <tr> <td class="col feed"><?php echo $block->escapeHtml($item['label']) ?></td> <td class="col action"> - <a href="<?php /* @escapeNotVerified */ echo $item['link'] ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> + <a href="<?php echo $block->escapeUrl($item['link']) ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> </td> </tr> <?php endforeach; ?> diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index a2999fe95d0..5d5b9d11241 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -41,7 +41,7 @@ </fieldset> </script> -<form action="<?php /* @escapeNotVerified */ echo $block->getSendUrl() ?>" method="post" id="product-sendtofriend-form" +<form action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" method="post" id="product-sendtofriend-form" data-mage-init='{ "rowBuilder":{ "rowTemplate":"#add-recipient-tmpl", @@ -49,7 +49,7 @@ "rowParentElem":"<div></div>", "remEventSelector":"button", "btnRemoveSelector":".action.remove", - "maxRows":"<?php /* @escapeNotVerified */ echo $block->getMaxRecipients() ?>", + "maxRows":"<?php echo (int)$block->getMaxRecipients() ?>", "maxRowsMsg":"#max-recipient-message", "addRowBtn":"#add-recipient-button", "additionalRowClass":"additional"}, -- GitLab From 4b82a15e0d76682dec0b425305502b5165dbb341 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Tue, 2 Aug 2016 10:32:19 +0300 Subject: [PATCH 100/838] MAGETWO-55754: [WCAG 2.0 AA] Image Gallery Thumbnails --- .../Magento/blank/Magento_Theme/web/css/source/_module.less | 2 +- .../Magento/luma/Magento_Theme/web/css/source/_module.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less index 41b2730ca58..7fb7985ada1 100644 --- a/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Theme/web/css/source/_module.less @@ -113,8 +113,8 @@ } .action-skip-wrapper { - position: relative; height: 0; + position: relative; } // diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less index cb7e3ef0c44..12ef890f430 100644 --- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less +++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less @@ -169,8 +169,8 @@ } .action-skip-wrapper { - position: relative; height: 0; + position: relative; } // -- GitLab From d9eafa6ee093ed9713020d862688b8b37d8cc3f7 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 2 Aug 2016 09:22:27 -0500 Subject: [PATCH 101/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../Magento/Customer/view/frontend/templates/address/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index e0fdca76852..a866b334b4b 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -220,7 +220,7 @@ "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, "defaultRegion": "<?php echo $block->escapeHtmlAttr($block->getRegionId()) ?>", - "countriesWithOptionalZip": <?php echo $block->escapeHtmlAttr($this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true)) ?> + "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } } -- GitLab From 555f914aa4f2c111580ee539e7c7c8c17ccd400a Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Tue, 2 Aug 2016 18:22:44 +0300 Subject: [PATCH 102/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - set focus on form first invalid input --- .../view/frontend/web/js/view/shipping.js | 17 ++++--- .../view/base/web/js/form/element/abstract.js | 2 +- .../Magento/Ui/view/base/web/js/form/form.js | 45 ++----------------- 3 files changed, 13 insertions(+), 51 deletions(-) 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 de9611f4a33..ddb62ceb37b 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 @@ -260,15 +260,14 @@ define( this.source.trigger('shippingAddress.custom_attributes.data.validate'); } - if (emailValidationResult) { - if (this.source.get('params.invalid') || - !quote.shippingMethod().method_code || - !quote.shippingMethod().carrier_code - ) { - this.focusInvalid(); - - return false; - } + if (emailValidationResult && + this.source.get('params.invalid') || + !quote.shippingMethod().method_code || + !quote.shippingMethod().carrier_code + ) { + this.focusInvalid(); + + return false; } shippingAddress = quote.shippingAddress(); diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index c3f7884f54e..40152bd9209 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -79,7 +79,7 @@ define([ * @returns {Boolean} */ isInvalid: function () { - return this.error() && this.error().length; + return this.error() && this.error().length ? this : false; }, /** diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js index 7cec82ac8e3..9e6ed07a96f 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -264,50 +264,13 @@ define([ * @returns {Object} */ focusInvalid: function () { - var scrollTop, invalidField = this.some('isInvalid'); - - if (typeof invalidField !== 'undefined') { - if (typeof invalidField.focused === 'function') { - invalidField.focused(true); - } else { - scrollTop = $(this.errorClass).offset().top - window.innerHeight / 2; - window.scrollTo(0, scrollTop); - } - } - - return this; - }, - - /** - * Tries to call specified method on an object or its children. - * Returns first object which pass the method test. - * - * @param {String} method - name of method for test - * @param {Object} [obj] - target object - * @returns {*} - */ - some: function (method, obj) { - var i, result, collection; + var invalidField = _.find(this.delegate('isInvalid')); - obj = obj || this; - - if (_.isFunction(obj[method]) && obj[method]()) { - result = obj; - } - - if (!result) { - collection = typeof obj.elems === 'function' ? obj.elems() : []; - - for (i in collection) { - if (collection.hasOwnProperty(i)) { - if (result = this.some(method, collection[i])) { - break; - } - } - } + if (typeof invalidField !== 'undefined' && typeof invalidField.focused === 'function') { + invalidField.focused(true); } - return result; + return this; }, /** -- GitLab From 83fe6332323c305f01cfccabc9fd7c7ea9fc6ed7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 2 Aug 2016 13:19:13 -0500 Subject: [PATCH 103/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../Captcha/view/adminhtml/templates/default.phtml | 10 +++++----- .../Cookie/view/frontend/templates/html/notices.phtml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index da3ec0a62ee..b4f1d095f45 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -19,7 +19,7 @@ id="captcha" class="admin__control-text" type="text" - name="<?php echo $block->escapeHtml(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtml($block->getFormId())?>]" + name="<?php echo $block->escapeHtmlAttr(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtml($block->getFormId())?>]" data-validate="{required:true}"/> <?php if ($captcha->isCaseSensitive()) :?> <div class="admin__field-note"> @@ -35,16 +35,16 @@ src="<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Captcha::reload.png')) ?>" alt="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"/> <img - id="<?php echo $block->escapeHtml($block->getFormId()) ?>" - width="<?php echo (int) $block->getImgWidth() ?>" - height="<?php echo (int) $block->getImgHeight() ?>" + id="<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" + width="<?php /* @noEscape */ echo (int) $block->getImgWidth() ?>" + height="<?php /* @noEscape */ echo (int) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>" /> </div> <script> require(["prototype", "mage/captcha"], function(){ //<![CDATA[ - var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeHtml($block->getFormId()) ?>'); + var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeJs($block->getFormId()) ?>'); $('captcha-reload').observe('click', function () { captcha.refresh(this); diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 63d6e253836..d223f7ec71f 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -27,7 +27,7 @@ "#notice-cookie-block": { "cookieNotices": { "cookieAllowButtonSelector": "#btn-cookie-allow", - "cookieName": "<?php echo $block->escapeHtml(\Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE) ?>", + "cookieName": "<?php echo $block->escapeJs(\Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE) ?>", "cookieValue": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, "cookieLifetime": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>, "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" -- GitLab From 1083fe01080599d38db5a4b39c07d269f18af64e Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Tue, 2 Aug 2016 13:54:57 -0500 Subject: [PATCH 104/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module - Removed all annotation from non-translation instances. --- .../adminhtml/templates/rating/detailed.phtml | 4 ++-- .../adminhtml/templates/rating/options.phtml | 8 ++++---- .../templates/rating/stars/detailed.phtml | 2 +- .../templates/rating/stars/summary.phtml | 2 +- .../adminhtml/templates/rss/grid/link.phtml | 2 +- .../frontend/templates/customer/list.phtml | 6 +++--- .../frontend/templates/customer/recent.phtml | 8 ++++---- .../frontend/templates/customer/view.phtml | 10 +++++----- .../view/frontend/templates/detailed.phtml | 2 +- .../Review/view/frontend/templates/form.phtml | 18 +++++++++--------- .../frontend/templates/helper/summary.phtml | 10 +++++----- .../templates/helper/summary_short.phtml | 8 ++++---- .../frontend/templates/product/view/list.phtml | 8 ++++---- .../templates/product/view/other.phtml | 2 +- .../view/frontend/templates/review.phtml | 2 +- .../Review/view/frontend/templates/view.phtml | 6 +++--- 16 files changed, 49 insertions(+), 49 deletions(-) diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml index cd095874006..173d421a052 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml @@ -15,8 +15,8 @@ <?php $_options = ($_rating->getRatingOptions()) ? $_rating->getRatingOptions() : $_rating->getOptions() ?> <div class="admin__field-control" data-widget="ratingControl"> <?php foreach (array_reverse($_options) as $_option): ?> - <input type="radio" name="ratings[<?php /* @escapeNotVerified */ echo($_rating->getVoteId()) ? $_rating->getVoteId() : $_rating->getId() ?>]" id="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>" value="<?php /* @escapeNotVerified */ echo $_option->getId() ?>" <?php if ($block->isSelected($_option, $_rating)): ?>checked="checked"<?php endif; ?> /> - <label for="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>">★</label> + <input type="radio" name="ratings[<?php /* @escapeNotVerified */ echo($_rating->getVoteId()) ? $_rating->getVoteId() : $_rating->getId() ?>]" id="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>" value="<?php echo $block->escapeHtmlAttr($_option->getId()) ?>" <?php if ($block->isSelected($_option, $_rating)): ?>checked="checked"<?php endif; ?> /> + <label for="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>">★</label> <?php $_iterator++ ?> <?php endforeach; ?> </div> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml index 19885077f1e..7ae36eacc1e 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml @@ -14,15 +14,15 @@ <?php if (!$options): ?> <?php for ($_i = 1;$_i <= 5;$_i++): ?> <span class="field-row"> - <label for="option_<?php /* @escapeNotVerified */ echo $_i ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> - <input id="option_<?php /* @escapeNotVerified */ echo $_i ?>" name="option[<?php /* @escapeNotVerified */ echo $_i ?>][code]" value="<?php /* @escapeNotVerified */ echo $_i ?>" class="input-text" type="text" /> + <label for="option_<?php echo $block->escapeHtmlAttr($_i) ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <input id="option_<?php echo $block->escapeHtmlAttr($_i) ?>" name="option[<?php echo $block->escapeHtmlAttr($_i) ?>][code]" value="<?php echo $block->escapeHtmlAttr($_i) ?>" class="input-text" type="text" /> </span> <?php endfor; ?> <?php elseif ($options->getSize() > 0): ?> <?php foreach ($options->getItems() as $_item): ?> <span class="field-row"> - <label for="option_<?php /* @escapeNotVerified */ echo $_item->getId() ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> - <input id="option_<?php /* @escapeNotVerified */ echo $_item->getId() ?>" name="option[<?php /* @escapeNotVerified */ echo $_item->getId() ?>][code]" value="<?php /* @escapeNotVerified */ echo $_item->getCode() ?>" class="input-text" type="text" /> + <label for="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <input id="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>" name="option[<?php echo $block->escapeHtmlAttr($_item->getId()) ?>][code]" value="<?php echo $block->escapeHtmlAttr($_item->getCode()) ?>" class="input-text" type="text" /> </span> <?php endforeach; ?> <?php endif; ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml index fab5a826616..bdc65c0fbbf 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml @@ -14,7 +14,7 @@ <div class="ratings"> <?php echo $block->escapeHtml($_rating->getRatingCode()) ?> <div class="rating-box"> - <div class="rating" style="width:<?php /* @escapeNotVerified */ echo ceil($_rating->getPercent()) ?>%;"></div> + <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getPercent()) ?>%;"></div> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml index 83ec4feafff..292cea00da6 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml @@ -9,7 +9,7 @@ ?> <?php if ($block->getRatingSummary()->getCount()): ?> <div class="rating-box"> - <div class="rating" style="width:<?php /* @escapeNotVerified */ echo ceil($block->getRatingSummary()->getSum() / ($block->getRatingSummary()->getCount())) ?>%;"></div> + <div class="rating" style="width:<?php /* @noEscape */ echo ceil($block->getRatingSummary()->getSum() / ($block->getRatingSummary()->getCount())) ?>%;"></div> </div> <?php else: ?> <?php /* @escapeNotVerified */ echo __("Rating isn't Available") ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml b/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml index 457b1e73f94..763d8e8ed29 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rss/grid/link.phtml @@ -9,5 +9,5 @@ /** @var $block \Magento\Review\Block\Adminhtml\Grid\Rss\Link */ ?> <?php if ($block->isRssAllowed() && $block->getLink()): ?> -<a href="<?php /* @escapeNotVerified */ echo $block->getLink() ?>" class="link-feed"><?php /* @escapeNotVerified */ echo $block->getLabel() ?></a> +<a href="<?php echo $block->escapeUrl($block->getLink()) ?>" class="link-feed"><?php echo $block->escapeHtml($block->getLabel()) ?></a> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index 24ab3a2b905..712532d355d 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -23,10 +23,10 @@ <tbody> <?php foreach ($block->getReviews() as $_review): ?> <tr> - <td data-th="<?php echo $block->escapeHtml(__('Created')) ?>" class="col date"><?php /* @escapeNotVerified */ echo $block->dateFormat($_review->getReviewCreatedAt()); ?></td> + <td data-th="<?php echo $block->escapeHtml(__('Created')) ?>" class="col date"><?php echo $block->escapeHtml($block->dateFormat($_review->getReviewCreatedAt())); ?></td> <td data-th="<?php echo $block->escapeHtml(__('Product Name')) ?>" class="col item"> <strong class="product-name"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductLink() ?>id/<?php /* @escapeNotVerified */ echo $_review->getEntityPkValue() ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a> + <a href="<?php echo $block->escapeUrl($block->getProductLink()) ?>id/<?php echo $block->escapeHtmlAttr($_review->getEntityPkValue()) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a> </strong> </td> <td data-th="<?php echo $block->escapeHtml(__('Rating')) ?>" class="col summary"> @@ -43,7 +43,7 @@ <?php echo $this->helper('Magento\Review\Helper\Data')->getDetailHtml($_review->getDetail()) ?> </td> <td data-th="<?php echo $block->escapeHtml(__('Actions')) ?>" class="col actions"> - <a href="<?php /* @escapeNotVerified */ echo $block->getReviewLink() ?>id/<?php /* @escapeNotVerified */ echo $_review->getReviewId() ?>" class="action more"> + <a href="<?php echo $block->escapeUrl($block->getReviewLink()) ?>id/<?php echo $block->escapeHtmlAttr($_review->getReviewId()) ?>" class="action more"> <span><?php /* @escapeNotVerified */ echo __('See Details') ?></span> </a> </td> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml index 143ad3ac0ce..2cc7a20bc3a 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml @@ -16,19 +16,19 @@ <div class="block block-reviews-dashboard"> <div class="block-title"> <strong><?php /* @escapeNotVerified */ echo __('My Recent Reviews') ?></strong> - <a class="action view" href="<?php /* @escapeNotVerified */ echo $block->getAllReviewsUrl() ?>"><span><?php /* @escapeNotVerified */ echo __('View All') ?></span></a> + <a class="action view" href="<?php echo $block->escapeUrl($block->getAllReviewsUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('View All') ?></span></a> </div> <div class="block-content"> <ol class="items"> <?php foreach ($block->getReviews() as $_review): ?> <li class="item"> - <strong class="product-name"><a href="<?php /* @escapeNotVerified */ echo $block->getReviewUrl($_review->getReviewId()) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a></strong> + <strong class="product-name"><a href="<?php echo $block->escapeUrl($block->getReviewUrl($_review->getReviewId())) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a></strong> <?php if ($_review->getSum()): ?> <?php $rating = $_review->getSum() / $_review->getCount() ?> <div class="rating-summary"> <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> - <div class="rating-result" title="<?php /* @escapeNotVerified */ echo $rating; ?>%"> - <span style="width:<?php /* @escapeNotVerified */ echo $rating; ?>%"><span><?php /* @escapeNotVerified */ echo $rating; ?>%</span></span> + <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> + <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"><span><?php echo $block->escapeHtml($rating); ?>%</span></span> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml index 1e031d02b49..64ac6d2e0e0 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml @@ -14,7 +14,7 @@ $product = $block->getProductData(); <div class="customer-review view"> <div class="product-details"> <div class="product-media"> - <a class="product-photo" href="<?php /* @escapeNotVerified */ echo $product->getProductUrl() ?>"> + <a class="product-photo" href="<?php echo $block->escapeUrl($product->getProductUrl()) ?>"> <?php /* customer_account_product_review_page */ ?> <?php echo $block->getImage($block->getProductData(), 'customer_account_product_review_page')->toHtml() ?> </a> @@ -39,9 +39,9 @@ $product = $block->getProductData(); <?php $rating = ceil($_rating->getPercent()) ?> <div class="rating-summary item"> <span class="rating-label"><span><?php echo $block->escapeHtml($_rating->getRatingCode()) ?></span></span> - <div class="rating-result" title="<?php /* @escapeNotVerified */ echo $rating; ?>%"> - <span style="width:<?php /* @escapeNotVerified */ echo $rating; ?>%"> - <span><?php /* @escapeNotVerified */ echo $rating; ?>%</span> + <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> + <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"> + <span><?php echo $block->escapeHtml($rating); ?>%</span> </span> </div> </div> @@ -59,7 +59,7 @@ $product = $block->getProductData(); </div> <div class="actions-toolbar"> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl() ?>"><span><?php /* @escapeNotVerified */ echo __('Back to My Reviews') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Back to My Reviews') ?></span></a> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/detailed.phtml b/app/code/Magento/Review/view/frontend/templates/detailed.phtml index adc9a0d2b4b..681eb4cf66f 100644 --- a/app/code/Magento/Review/view/frontend/templates/detailed.phtml +++ b/app/code/Magento/Review/view/frontend/templates/detailed.phtml @@ -18,7 +18,7 @@ <th class="label" scope="row"><?php echo __($block->escapeHtml($_rating->getRatingCode())) ?></th> <td class="value"> <div class="rating box"> - <div class="rating" style="width:<?php /* @escapeNotVerified */ echo ceil($_rating->getSummary()) ?>%;"></div> + <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getSummary()) ?>%;"></div> </div> </td> </tr> diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index b912cf0173f..947184b1a5e 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -14,7 +14,7 @@ <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Write Your Own Review') ?></strong></div> <div class="block-content"> <?php if ($block->getAllowWriteReviewFlag()): ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getAction() ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'"> +<form action="<?php echo $block->escapeHtmlAttr($block->getAction()) ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'"> <?php echo $block->getBlockHtml('formkey'); ?> <?php echo $block->getChildHtml('form_fields_before')?> <fieldset class="fieldset review-fieldset" data-hasrequired="<?php __('* Required Fields'); ?>"> @@ -33,17 +33,17 @@ <?php $iterator = 1; foreach ($options as $_option): ?> <input type="radio" - name="ratings[<?php /* @escapeNotVerified */ echo $_rating->getId() ?>]" - id="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>" - value="<?php /* @escapeNotVerified */ echo $_option->getId() ?>" + name="ratings[<?php echo $block->escapeHtmlAttr($_rating->getId()) ?>]" + id="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>" + value="<?php echo $block->escapeHtmlAttr($_option->getId()) ?>" class="radio" data-validate="{required:true, messages:{required:'Please select one of each of the ratings above.'}}" - aria-labelledby="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_rating_label <?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>_label" /> + aria-labelledby="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_rating_label <?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>_label" /> <label - class="rating-<?php /* @escapeNotVerified */ echo $iterator; ?>" - for="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>" + class="rating-<?php echo $block->escapeHtmlAttr($iterator); ?>" + for="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>" title="<?php /* @escapeNotVerified */ echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?>" - id="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>_label"> + id="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>_label"> <span><?php /* @escapeNotVerified */ echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?></span> </label> <?php $iterator++; ?> @@ -84,7 +84,7 @@ <script type="text/x-magento-init"> { "[data-role=product-review-form]": { - "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?> + "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> }, "#review-form": { "Magento_Review/js/error-placement": {} diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml index 6aceecfe692..2079bed1cf8 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml @@ -15,20 +15,20 @@ <?php if ($rating):?> <div class="rating-summary"> <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> - <div class="rating-result" title="<?php /* @escapeNotVerified */ echo $rating; ?>%"> - <span style="width:<?php /* @escapeNotVerified */ echo $rating; ?>%"><span><span itemprop="ratingValue"><?php /* @escapeNotVerified */ echo $rating; ?></span>% of <span itemprop="bestRating">100</span></span></span> + <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> + <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"><span><span itemprop="ratingValue"><?php echo $block->escapeHtml($rating); ?></span>% of <span itemprop="bestRating">100</span></span></span> </div> </div> <?php endif;?> <div class="reviews-actions"> - <a class="action view" href="<?php /* @escapeNotVerified */ echo $url ?>"><span itemprop="reviewCount"><?php /* @escapeNotVerified */ echo $block->getReviewsCount() ?></span> <span><?php /* @escapeNotVerified */ echo($block->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> - <a class="action add" href="<?php /* @escapeNotVerified */ echo $urlForm ?>"><?php /* @escapeNotVerified */ echo __('Add Your Review') ?></a> + <a class="action view" href="<?php echo $block->escapeUrl($url) ?>"><span itemprop="reviewCount"><?php echo $block->escapeHtml($block->getReviewsCount()) ?></span> <span><?php /* @escapeNotVerified */ echo($block->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> + <a class="action add" href="<?php echo $block->escapeUrl($urlForm) ?>"><?php /* @escapeNotVerified */ echo __('Add Your Review') ?></a> </div> </div> <?php elseif ($block->getDisplayIfEmpty()): ?> <div class="product-reviews-summary empty"> <div class="reviews-actions"> - <a class="action add" href="<?php /* @escapeNotVerified */ echo $urlForm; ?>"> + <a class="action add" href="<?php echo $block->escapeUrl($urlForm); ?>"> <?php /* @escapeNotVerified */ echo __('Be the first to review this product') ?> </a> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml index 45f5515dd5a..df0a28de4c3 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml @@ -15,19 +15,19 @@ <?php if ($rating):?> <div class="rating-summary"> <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> - <div class="rating-result" title="<?php /* @escapeNotVerified */ echo $rating; ?>%"> - <span style="width:<?php /* @escapeNotVerified */ echo $rating; ?>%"><span><?php /* @escapeNotVerified */ echo $rating; ?>%</span></span> + <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> + <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"><span><?php echo $block->escapeHtml($rating); ?>%</span></span> </div> </div> <?php endif;?> <div class="reviews-actions"> - <a class="action view" href="<?php /* @escapeNotVerified */ echo $url ?>"><?php /* @escapeNotVerified */ echo $block->getReviewsCount() ?> <span><?php /* @escapeNotVerified */ echo($block->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> + <a class="action view" href="<?php echo $block->escapeUrl($url) ?>"><?php echo $block->escapeHtml($block->getReviewsCount()) ?> <span><?php /* @escapeNotVerified */ echo($block->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> </div> </div> <?php elseif ($block->getDisplayIfEmpty()): ?> <div class="product-reviews-summary short empty"> <div class="reviews-actions"> - <a class="action add" href="<?php /* @escapeNotVerified */ echo $urlForm; ?>"> + <a class="action add" href="<?php echo $block->escapeUrl($urlForm); ?>"> <?php /* @escapeNotVerified */ echo __('Be the first to review this product') ?> </a> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml index 585ffe01de0..7e76316a210 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml @@ -35,11 +35,11 @@ <?php foreach ($_review->getRatingVotes() as $_vote): ?> <div class="rating-summary item" itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating"> <span class="label rating-label"><span><?php echo $block->escapeHtml($_vote->getRatingCode()) ?></span></span> - <div class="rating-result" title="<?php /* @escapeNotVerified */ echo $_vote->getPercent() ?>%"> + <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($_vote->getPercent()) ?>%"> <meta itemprop="worstRating" content = "1"/> <meta itemprop="bestRating" content = "100"/> - <span style="width:<?php /* @escapeNotVerified */ echo $_vote->getPercent() ?>%"> - <span itemprop="ratingValue"><?php /* @escapeNotVerified */ echo $_vote->getPercent() ?>%</span> + <span style="width:<?php echo $block->escapeHtmlAttr($_vote->getPercent()) ?>%"> + <span itemprop="ratingValue"><?php echo $block->escapeHtml($_vote->getPercent()) ?>%</span> </span> </div> </div> @@ -56,7 +56,7 @@ </p> <p class="review-date"> <span class="review-details-label"><?php /* @escapeNotVerified */ echo __('Posted on') ?></span> - <time class="review-details-value" itemprop="datePublished" datetime="<?php /* @escapeNotVerified */ echo $block->formatDate($_review->getCreatedAt(), $format) ?>"><?php /* @escapeNotVerified */ echo $block->formatDate($_review->getCreatedAt(), $format) ?></time> + <time class="review-details-value" itemprop="datePublished" datetime="<?php echo $block->escapeHtmlAttr($block->formatDate($_review->getCreatedAt(), $format)) ?>"><?php echo $block->escapeHtml($block->formatDate($_review->getCreatedAt(), $format)) ?></time> </p> </div> </li> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml index 5e56f99483c..48222c4e8ea 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml @@ -11,5 +11,5 @@ <?php /** @var $block \Magento\Review\Block\Product\View\Other */ ?> <?php $_product = $block->getProduct(); ?> <div class="actions"> - <a href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Main Product Info') ?></span></a> + <a href="<?php echo $block->escapeUrl($_product->getProductUrl()) ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Main Product Info') ?></span></a> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml index 93dfe7766c2..4729ffa173f 100644 --- a/app/code/Magento/Review/view/frontend/templates/review.phtml +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -12,7 +12,7 @@ { "*": { "Magento_Review/js/process-reviews": { - "productReviewUrl": "<?php /* @escapeNotVerified */ echo $block->getProductReviewUrl();?>" + "productReviewUrl": "<?php echo $block->escapeUrl($block->getProductReviewUrl());?>" } } } diff --git a/app/code/Magento/Review/view/frontend/templates/view.phtml b/app/code/Magento/Review/view/frontend/templates/view.phtml index 3fdd53c050c..f44d31d63f7 100644 --- a/app/code/Magento/Review/view/frontend/templates/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/view.phtml @@ -14,7 +14,7 @@ <h1><?php /* @escapeNotVerified */ echo __('Review Details') ?></h1> </div> <div class="product-img-box"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductData()->getProductUrl() ?>"> + <a href="<?php echo $block->escapeUrl($block->getProductData()->getProductUrl()) ?>"> <?php echo $block->getImage($block->getProductData(), 'product_base_image', ['class' => 'product-image'])->toHtml(); ?> </a> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> @@ -35,7 +35,7 @@ <td class="label"><?php echo __($block->escapeHtml($_rating->getRatingCode())) ?></td> <td class="value"> <div class="rating-box"> - <div class="rating" style="width:<?php /* @escapeNotVerified */ echo ceil($_rating->getPercent()) ?>%;"></div> + <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getPercent()) ?>%;"></div> </div></td> </tr> <?php endif; ?> @@ -48,7 +48,7 @@ </div> <div class="actions"> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl() ?>"> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"> <span><?php /* @escapeNotVerified */ echo __('Back to Product Reviews') ?></a></span> </a> </div> -- GitLab From 433bc25d2f2e2f253990b5a2cb0de0e7a3b1de62 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Tue, 2 Aug 2016 14:47:44 -0500 Subject: [PATCH 105/838] MAGETWO-55921: Eliminate @escapeNotVerified in Newsletter Module - Addressed CR comments. --- .../Newsletter/view/adminhtml/templates/queue/edit.phtml | 1 + .../Newsletter/view/adminhtml/templates/subscriber/list.phtml | 2 ++ .../Newsletter/view/adminhtml/templates/template/edit.phtml | 1 + .../Magento/Newsletter/view/frontend/templates/subscribe.phtml | 2 ++ 4 files changed, 6 insertions(+) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml index cc5df715b14..dbc2fcf0ea6 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/queue/edit.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /* @var $block \Magento\Newsletter\Block\Adminhtml\Queue\Edit */ + ?> <div data-mage-init='{"floatingHeader": {}}' class="page-actions"> <?php echo $block->getBackButtonHtml() ?> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml index 9f372679d32..c4092625f20 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Newsletter\Block\Adminhtml\Subscriber $block */ + ?> <?php echo $block->getChildHtml('grid') ?> <?php if (count($block->getQueueAsOptions())>0 && $block->getShowQueueAdd()): ?> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index 59445f029b1..db61ffadc98 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -9,6 +9,7 @@ use Magento\Framework\App\TemplateTypesInterface; // @codingStandardsIgnoreFile /* @var $block \Magento\Newsletter\Block\Adminhtml\Template\Edit */ + ?> <form action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" method="post" id="newsletter_template_edit_form"> <?php echo $block->getBlockHtml('formkey')?> diff --git a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml index ec36fa204fd..5894c9f8681 100644 --- a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml +++ b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Newsletter\Block\Subscribe $block */ + ?> <div class="block newsletter"> <div class="title"><strong>Newsletter</strong></div> -- GitLab From 9933956662bcf02d7e1df9a289225f4aba6faa58 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Tue, 2 Aug 2016 14:55:38 -0500 Subject: [PATCH 106/838] MAGETWO-55922: Eliminate @escapeNotVerified in ProductAlert Module - Fixed incorrect escaping method. --- .../ProductAlert/view/frontend/templates/product/view.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml b/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml index dd65bb07a60..3847759e19c 100644 --- a/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml +++ b/app/code/Magento/ProductAlert/view/frontend/templates/product/view.phtml @@ -6,7 +6,7 @@ ?> <?php /* @var $block \Magento\ProductAlert\Block\Product\View */?> <div class="product alert <?php echo $block->getHtmlClass() ?>"> - <a href="#" data-post='<?php echo $block->escapeUrl($block->getPostAction()); ?>' + <a href="#" data-post='<?php /* @noEscape */ echo $block->getPostAction(); ?>' title="<?php echo $block->escapeHtml(__($block->getSignupLabel())); ?>" class="action alert"> <?php echo $block->escapeHtml(__($block->getSignupLabel())); ?> </a> -- GitLab From 87e0ac95143da60fe7bcc8d951c22ddb00a6fa8f Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 2 Aug 2016 16:30:33 -0500 Subject: [PATCH 107/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../frontend/templates/account/authentication-popup.phtml | 2 +- .../Customer/view/frontend/templates/address/edit.phtml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index 0554f21447d..2636887b23f 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -18,7 +18,7 @@ "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> }, "*": { - "Magento_Ui/js/block-loader": "<?php echo $bock->escapeUrl($block->getViewFileUrl('images/loader-1.gif')); ?>" + "Magento_Ui/js/block-loader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-1.gif')); ?>" } } </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index a866b334b4b..8ba5e82275a 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -80,14 +80,14 @@ <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?> <?php for ($_i = 1, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i < $_n; $_i++): ?> <div class="field additional"> - <label class="label" for="street_<?php echo $_i+1 ?>"> + <label class="label" for="street_<?php /* @noEscape */ echo $_i+1 ?>"> <span><?php /* @escapeNotVerified */ echo __('Street Address %1', $_i+1) ?></span> </label> <div class="control"> <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getStreetLine($_i + 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i + 1) ?>" - id="street_<?php echo $_i + 1 ?>" + id="street_<?php /* @noEscape */ echo $_i + 1 ?>" class="<?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> </div> -- GitLab From f6cc21bb09c38350b50ddf4e1149251763004087 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 2 Aug 2016 17:12:05 -0500 Subject: [PATCH 108/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- .../Review/Block/Customer/ListCustomer.php | 24 +++++++++++++++++++ .../adminhtml/templates/rating/detailed.phtml | 4 ++-- .../adminhtml/templates/rating/options.phtml | 4 ++-- .../frontend/templates/customer/list.phtml | 4 ++-- .../Review/view/frontend/templates/form.phtml | 4 ++-- .../view/frontend/templates/review.phtml | 2 +- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Review/Block/Customer/ListCustomer.php b/app/code/Magento/Review/Block/Customer/ListCustomer.php index 4ab75e2c99e..d596f1d46db 100644 --- a/app/code/Magento/Review/Block/Customer/ListCustomer.php +++ b/app/code/Magento/Review/Block/Customer/ListCustomer.php @@ -118,22 +118,46 @@ class ListCustomer extends \Magento\Customer\Block\Account\Dashboard * Get review link * * @return string + * @deprecated */ public function getReviewLink() { return $this->getUrl('review/customer/view/'); } + /** + * Get review URL + * + * @param \Magento\Review\Model\Review $review + * @return string + */ + public function getReviewUrl($review) + { + return $this->getUrl('review/customer/view', ['id' => $review->getReviewId()]); + } + /** * Get product link * * @return string + * @deprecated */ public function getProductLink() { return $this->getUrl('catalog/product/view/'); } + /** + * Get product URL + * + * @param \Magento\Review\Model\Review $review + * @return string + */ + public function getProductUrl($review) + { + return $this->getUrl('catalog/product/view', ['id' => $review->getEntityPkValue()]); + } + /** * Format date in short format * diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml index 173d421a052..089fd7a3dc1 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml @@ -15,8 +15,8 @@ <?php $_options = ($_rating->getRatingOptions()) ? $_rating->getRatingOptions() : $_rating->getOptions() ?> <div class="admin__field-control" data-widget="ratingControl"> <?php foreach (array_reverse($_options) as $_option): ?> - <input type="radio" name="ratings[<?php /* @escapeNotVerified */ echo($_rating->getVoteId()) ? $_rating->getVoteId() : $_rating->getId() ?>]" id="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>" value="<?php echo $block->escapeHtmlAttr($_option->getId()) ?>" <?php if ($block->isSelected($_option, $_rating)): ?>checked="checked"<?php endif; ?> /> - <label for="<?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>">★</label> + <input type="radio" name="ratings[<?php echo $block->escapeHtmlAttr($_rating->getVoteId() ? $_rating->getVoteId() : $_rating->getId()) ?>]" id="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>" value="<?php echo $block->escapeHtmlAttr($_option->getId()) ?>" <?php if ($block->isSelected($_option, $_rating)): ?>checked="checked"<?php endif; ?> /> + <label for="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>">★</label> <?php $_iterator++ ?> <?php endforeach; ?> </div> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml index 7ae36eacc1e..b0712f11dec 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml @@ -14,8 +14,8 @@ <?php if (!$options): ?> <?php for ($_i = 1;$_i <= 5;$_i++): ?> <span class="field-row"> - <label for="option_<?php echo $block->escapeHtmlAttr($_i) ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> - <input id="option_<?php echo $block->escapeHtmlAttr($_i) ?>" name="option[<?php echo $block->escapeHtmlAttr($_i) ?>][code]" value="<?php echo $block->escapeHtmlAttr($_i) ?>" class="input-text" type="text" /> + <label for="option_<?php /* @noEscape */ echo $_i ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <input id="option_<?php /* @noEscape */ echo $_i ?>" name="option[<?php /* @noEscape */ echo $_i ?>][code]" value="<?php /* @noEscape */ echo $_i ?>" class="input-text" type="text" /> </span> <?php endfor; ?> <?php elseif ($options->getSize() > 0): ?> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index 712532d355d..e3d8aad8bc9 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -26,7 +26,7 @@ <td data-th="<?php echo $block->escapeHtml(__('Created')) ?>" class="col date"><?php echo $block->escapeHtml($block->dateFormat($_review->getReviewCreatedAt())); ?></td> <td data-th="<?php echo $block->escapeHtml(__('Product Name')) ?>" class="col item"> <strong class="product-name"> - <a href="<?php echo $block->escapeUrl($block->getProductLink()) ?>id/<?php echo $block->escapeHtmlAttr($_review->getEntityPkValue()) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a> + <a href="<?php echo $block->escapeUrl($block->getProductUrl()) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a> </strong> </td> <td data-th="<?php echo $block->escapeHtml(__('Rating')) ?>" class="col summary"> @@ -43,7 +43,7 @@ <?php echo $this->helper('Magento\Review\Helper\Data')->getDetailHtml($_review->getDetail()) ?> </td> <td data-th="<?php echo $block->escapeHtml(__('Actions')) ?>" class="col actions"> - <a href="<?php echo $block->escapeUrl($block->getReviewLink()) ?>id/<?php echo $block->escapeHtmlAttr($_review->getReviewId()) ?>" class="action more"> + <a href="<?php echo $block->escapeUrl($block->getReviewUrl($_review)) ?>" class="action more"> <span><?php /* @escapeNotVerified */ echo __('See Details') ?></span> </a> </td> diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index 947184b1a5e..a63adcce56d 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -14,7 +14,7 @@ <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Write Your Own Review') ?></strong></div> <div class="block-content"> <?php if ($block->getAllowWriteReviewFlag()): ?> -<form action="<?php echo $block->escapeHtmlAttr($block->getAction()) ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'"> +<form action="<?php echo $block->escapeUrl($block->getAction()) ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'"> <?php echo $block->getBlockHtml('formkey'); ?> <?php echo $block->getChildHtml('form_fields_before')?> <fieldset class="fieldset review-fieldset" data-hasrequired="<?php __('* Required Fields'); ?>"> @@ -84,7 +84,7 @@ <script type="text/x-magento-init"> { "[data-role=product-review-form]": { - "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> + "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout(); ?> }, "#review-form": { "Magento_Review/js/error-placement": {} diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml index 4729ffa173f..82ef2098f33 100644 --- a/app/code/Magento/Review/view/frontend/templates/review.phtml +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -12,7 +12,7 @@ { "*": { "Magento_Review/js/process-reviews": { - "productReviewUrl": "<?php echo $block->escapeUrl($block->getProductReviewUrl());?>" + "productReviewUrl": "<?php echo $block->escapeUrl($block->getProductReviewUrl()); ?>" } } } -- GitLab From e808e11dd05c1016e94110d6d047988f4ba2d2ee Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 2 Aug 2016 15:33:59 -0500 Subject: [PATCH 109/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../customer/edit/tab/wishlist.phtml | 8 +++---- .../frontend/templates/button/share.phtml | 4 ++-- .../frontend/templates/button/tocart.phtml | 4 ++-- .../frontend/templates/button/update.phtml | 4 ++-- .../renderer/actions/move_to_wishlist.phtml | 2 +- .../catalog/product/list/addto/wishlist.phtml | 2 +- .../catalog/product/view/addto/wishlist.phtml | 2 +- .../view/frontend/templates/email/items.phtml | 6 ++--- .../templates/item/column/actions.phtml | 6 ++--- .../frontend/templates/item/column/cart.phtml | 18 +++++++------- .../templates/item/column/comment.phtml | 8 +++---- .../frontend/templates/item/column/edit.phtml | 4 ++-- .../templates/item/column/image.phtml | 4 ++-- .../frontend/templates/item/column/name.phtml | 6 ++--- .../templates/item/column/price.phtml | 4 ++-- .../templates/item/column/remove.phtml | 4 ++-- .../templates/item/configure/addto.phtml | 4 ++-- .../item/configure/addto/wishlist.phtml | 2 +- .../view/frontend/templates/item/list.phtml | 4 ++-- .../messages/addProductSuccessMessage.phtml | 4 ++-- .../frontend/templates/options_list.phtml | 4 ++-- .../frontend/templates/rss/wishlist.phtml | 2 +- .../view/frontend/templates/shared.phtml | 24 +++++++++---------- .../view/frontend/templates/sharing.phtml | 18 +++++++------- .../view/frontend/templates/sidebar.phtml | 16 ++++++------- .../view/frontend/templates/view.phtml | 4 ++-- 26 files changed, 84 insertions(+), 84 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index 7f7120bc8b5..af308a9dbf7 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -24,13 +24,13 @@ if (!urlParams) { urlParams = ''; } - var url = <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; + var url = <?php echo $block->escapeJs($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; new Ajax.Updater( - <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.containerId, + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.containerId, url, { parameters: {form_key: FORM_KEY}, - onComplete: <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeHtml($block->getJsObjectName()) ?>), + onComplete: <?php echo $block->escapeJs($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeJs($block->getJsObjectName()) ?>), evalScripts:true } ); @@ -53,7 +53,7 @@ var self = this; confirm({ - content: '<?php /* @noEscape */ echo __('Are you sure you want to remove this item?') ?>', + content: '<?php /* @escapeNotVerified */ echo __('Are you sure you want to remove this item?') ?>', actions: { confirm: function () { self.reload('&delete=' + itemId); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml index fd0884337ee..e516d39d11c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml @@ -10,7 +10,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->getShared() < $block->getConfig()->getSharingEmailLimit()): ?> - <button type="submit" name="save_and_share" title="<?php /* @noEscape */ echo __('Share Wish List') ?>" class="action share"> - <span><?php /* @noEscape */ echo __('Share Wish List') ?></span> + <button type="submit" name="save_and_share" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action share"> + <span><?php /* @escapeNotVerified */ echo __('Share Wish List') ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml index c0f113ac5f0..1fc4b5fe4f8 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml @@ -11,7 +11,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->isSalable()): ?> - <button type="button" data-role="all-tocart" title="<?php /* @noEscape */ echo __('Add All to Cart') ?>" class="action tocart"> - <span><?php /* @noEscape */ echo __('Add All to Cart') ?></span> + <button type="button" data-role="all-tocart" title="<?php /* @escapeNotVerified */ echo __('Add All to Cart') ?>" class="action tocart"> + <span><?php /* @escapeNotVerified */ echo __('Add All to Cart') ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml index 8af9851095b..8ea857b1195 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml @@ -11,7 +11,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount()): ?> - <button type="submit" name="do" title="<?php /* @noEscape */ echo __('Update Wish List') ?>" class="action update"> - <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> + <button type="submit" name="do" title="<?php /* @escapeNotVerified */ echo __('Update Wish List') ?>" class="action update"> + <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml index 3de61a566b3..01302361efa 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml @@ -13,6 +13,6 @@ <a href="#" data-post='<?php /* @noEscape */ echo $block->getMoveFromCartParams(); ?>' class="use-ajax action action-towishlist"> - <span><?php /* @noEscape */ echo __('Move to Wishlist'); ?></span> + <span><?php /* @escapeNotVerified */ echo __('Move to Wishlist'); ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index df483967d00..292fe608106 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -16,6 +16,6 @@ data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' data-action="add-to-wishlist" role="button"> - <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml index f70dcafbe72..8f033e64fe6 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml @@ -13,7 +13,7 @@ <a href="#" class="action towishlist" data-post='<?php /* @noEscape */ echo $block->getWishlistParams(); ?>' - data-action="add-to-wishlist"><span><?php /* @noEscape */ echo __('Add to Wish List') ?></span></a> + data-action="add-to-wishlist"><span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span></a> <?php endif; ?> <script type="text/x-magento-init"> { diff --git a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml index ed974197c16..b573b9126a0 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml @@ -21,7 +21,7 @@ <td class="col product"> <p> <a href="<?= $block->escapeUrl($block->getProductUrl($_product)) ?>"> - <?php echo $block->escapeHtml($block->getImage($_product, 'product_small_image')->toHtml()); ?> + <?php /* @noEscape */ echo $block->getImage($_product, 'product_small_image')->toHtml(); ?> </a> </p> @@ -32,13 +32,13 @@ </p> <?php if ($block->hasDescription($item)): ?> <p> - <strong><?= /* @noEscape */ __('Comment') ?>:</strong> + <strong><?= /* @escapeNotVerified */ __('Comment') ?>:</strong> <br/><?= /* @noEscape */ $block->getEscapedDescription($item) ?> </p> <?php endif; ?> <p> <a href="<?= $block->escapeUrl($block->getProductUrl($_product)) ?>"> - <?= /* @noEscape */ __('View Product') ?> + <?= /* @escapeNotVerified */ __('View Product') ?> </a> </p> </td> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index 7fb68d570cf..e40238035f4 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -6,13 +6,13 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ -/* @var \Magento\Wishlist\Model\Item $item */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions */ +/* @var $item \Magento\Wishlist\Model\Item */ ?> <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> - <div class="<?php echo $block->escapeHtml($block->getCssClass()) ?>"> + <div class="<?php echo $block->escapeHtmlAttr($block->getCssClass()) ?>"> <?php foreach ($children as $childName):?> <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false);?> <?php endforeach;?> 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 d3fabc1cdf5..23307b35df2 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 @@ -20,29 +20,29 @@ $product = $item->getProduct(); <fieldset class="fieldset"> <?php if ($item->canHaveQty() && $product->isVisibleInSiteVisibility()): ?> <div class="field qty"> - <label class="label" for="qty[<?php echo $block->escapeHtml($item->getId()) ?>]"><span><?php /* @noEscape */ echo __('Qty') ?></span></label> + <label class="label" for="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label> <div class="control"> - <input type="number" data-role="qty" id="qty[<?php echo $block->escapeHtml($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" - name="qty[<?php echo $block->escapeHtml($item->getId()) ?>]" value="<?php echo (int)($block->getAddToCartQty($item) * 1) ?>"> + <input type="number" data-role="qty" id="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" + name="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]" value="<?php /* @noEscape */ echo (int)($block->getAddToCartQty($item) * 1) ?>"> </div> </div> <?php endif; ?> <?php if ($product->isSaleable()): ?> <div class="product-item-actions"> <div class="actions-primary"> - <button type="button" data-role="tocart" data-post='<?php /* @noEscape */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtml($item->getId())?>" class="action tocart primary"> - <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> + <button type="button" data-role="tocart" data-post='<?php /* @noEscape */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtmlAttr($item->getId())?>" class="action tocart primary"> + <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> </div> </div> <?php else: ?> <?php if ($product->getIsSalable()): ?> - <p class="available stock" title="<?php /* @noEscape */ echo __('Availability') ?>"> - <span><?php /* @noEscape */ echo __('In stock') ?></span> + <p class="available stock" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>"> + <span><?php /* @escapeNotVerified */ echo __('In stock') ?></span> </p> <?php else: ?> - <p class="unavailable stock" title="<?php /* @noEscape */ echo __('Availability') ?>"> - <span><?php /* @noEscape */ echo __('Out of stock') ?></span> + <p class="unavailable stock" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>"> + <span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span> </p> <?php endif; ?> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index 4ed780c1c7d..a3ef2d53f34 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column $block */ +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Comment $block */ /* @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); @@ -14,10 +14,10 @@ $item = $block->getItem(); ?> <div class="field comment-box"> - <label class="label" for="product-item-comment-<?php echo $block->escapeHtml($item->getWishlistItemId()) ?>"> - <span><?php /* @noEscape */ echo __('Comment') ?></span> + <label class="label" for="product-item-comment-<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>"> + <span><?php /* @escapeNotVerified */ echo __('Comment') ?></span> </label> <div class="control"> - <textarea id="product-item-comment-<?php echo $block->escapeHtml($item->getWishlistItemId()) ?>" placeholder="<?php /* @noEscape */ echo $this->helper('Magento\Wishlist\Helper\Data')->defaultCommentString() ?>" name="description[<?php echo $block->escapeHtml($item->getWishlistItemId()) ?>]" title="<?php /* @noEscape */ echo __('Comment') ?>" class="product-item-comment"><?php echo($block->escapeHtml($item->getDescription())) ?></textarea> + <textarea id="product-item-comment-<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>" placeholder="<?php /* @noEscape */ echo $this->helper('Magento\Wishlist\Helper\Data')->defaultCommentString() ?>" name="description[<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>]" title="<?php /* @escapeNotVerified */ echo __('Comment') ?>" class="product-item-comment"><?php echo($block->escapeHtml($item->getDescription())) ?></textarea> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index b0901c86876..0c454e38e6b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\AbstractBlock */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); @@ -16,6 +16,6 @@ $product = $item->getProduct(); <?php if ($product->isVisibleInSiteVisibility()): ?> <a class="action edit" href="<?php echo $block->escapeUrl($block->getItemConfigureUrl($item)) ?>"> - <span><?php /* @noEscape */ echo __('Edit') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Edit') ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml index 703dad67ec7..19b278185a3 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml @@ -6,13 +6,13 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\AbstractBlock */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); ?> -<a class="product-item-photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> +<a class="product-item-photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtmlAttr($product->getName()) ?>"> <?php echo $block->getImage($product, 'wishlist_thumbnail')->toHtml(); ?> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml index 8b06cacec5e..ddb06755d46 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml @@ -6,15 +6,15 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\AbstractBlock */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info */ -/** @var \Magento\Wishlist\Model\Item $item */ +/** @var $item \Magento\Wishlist\Model\Item */ $item = $block->getItem(); $product = $item->getProduct(); ?> <strong class="product-item-name"> - <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>" class="product-item-link"> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtmlAttr($product->getName()) ?>" class="product-item-link"> <?php echo $block->escapeHtml($product->getName()) ?> </a> </strong> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml index b207a42a156..767ece01986 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml @@ -6,11 +6,11 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\AbstractBlock */ +/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart */ /** @var \Magento\Wishlist\Model\Item $item */ ?> <?php foreach ($block->getChildNames() as $childName): ?> - <?php echo $block->escapeHtml($block->getLayout()->renderElement($childName, false)); ?> + <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false); ?> <?php endforeach;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index bd5690fe4c5..433440d1611 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -10,6 +10,6 @@ ?> -<a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @noEscape */ echo __('Remove Item') ?>" class="btn-remove action delete"> - <span><?php /* @noEscape */ echo __('Remove item');?></span> +<a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @escapeNotVerified */ echo __('Remove Item') ?>" class="btn-remove action delete"> + <span><?php /* @escapeNotVerified */ echo __('Remove item');?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml index f91e4e235e0..d285d41bdf8 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml @@ -13,14 +13,14 @@ <div class="product-addto-links" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> - <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <?php $_product = $block->getProduct(); ?> <?php $_compareUrl = $this->helper('Magento\Catalog\Helper\Product\Compare')->getAddUrl($_product); ?> <?php if ($_compareUrl) : ?> <a href="<?php echo $block->escapeUrl($_compareUrl) ?>" class="action tocompare"> - <span><?php /* @noEscape */ echo __('Add to Compare') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span> </a> <?php endif; ?> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml index dd209311ed5..651f6108e45 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml @@ -11,7 +11,7 @@ ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> - <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <script type="text/x-magento-init"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml index 46856248730..b5f56833316 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml @@ -18,7 +18,7 @@ $columns = $block->getColumns(); <?php if (count($block->getItems())): ?> <ol class="product-items"> <?php foreach ($block->getItems() as $item): ?> - <?php /* @noEscape */ echo($iterator++ == 1) ? '<li data-row="product-item" class="product-item" id="item_' . $block->escapeHtml($item->getId()) . '">' : '</li><li class="product-item" id="item_' . $block->escapeHtml($item->getId()) . '">' ?> + <?php /* @noEscape */ echo($iterator++ == 1) ? '<li data-row="product-item" class="product-item" id="item_' . $block->escapeHtmlAttr($item->getId()) . '">' : '</li><li class="product-item" id="item_' . $block->escapeHtmlAttr($item->getId()) . '">' ?> <div class="product-item-info"> <?php foreach ($columns as $column): ?> <?php $column->setItem($item); echo $column->toHtml($item);?> @@ -29,7 +29,7 @@ $columns = $block->getColumns(); </ol> <?php else: ?> <div class="message info empty"> - <span><?php /* @noEscape */ echo __('This Wish List has no Items');?></span> + <span><?php /* @escapeNotVerified */ echo __('This Wish List has no Items');?></span> </div> <?php endif; ?> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml index 6c20828f4d9..4a06e3489c9 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml @@ -4,8 +4,8 @@ * See COPYING.txt for license details. */ -/** @var \Magento\Framework\View\Element\Template $block */ +/** @var $block \Magento\Framework\View\Element\Template */ ?> -<?php /* @escapeVerified */ echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php /* @escapeVerified */ echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); +<?php /* @escapeNotVerified */ echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php /* @escapeNotVerified */ echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index 68f52c7ca81..480266c466d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -13,9 +13,9 @@ <?php $options = $block->getOptionList(); ?> <?php if ($options): ?> <div class="tooltip wrapper product-item-tooltip"> - <span class="action details tooltip toggle"><?php /* @noEscape */ echo __('See Details') ?></span> + <span class="action details tooltip toggle"><?php /* @escapeNotVerified */ echo __('See Details') ?></span> <div class="tooltip content"> - <strong class="subtitle"><?php /* @noEscape */ echo __('Options Details'); ?></strong> + <strong class="subtitle"><?php /* @escapeNotVerified */ echo __('Options Details'); ?></strong> <dl> <?php foreach ($options as $option): ?> <dt class="label"><?php echo $block->escapeHtml($option['label']) ?></dt> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml index 7bffc0f5512..475a1c4c8b6 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml @@ -11,6 +11,6 @@ ?> <?php if ($block->isRssAllowed() && $block->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?> <a href="<?php echo $block->escapeUrl($block->getLink()); ?>" class="action rss wishlist"> - <span><?php /* @noEscape */ echo __('RSS Feed') ?></span> + <span><?php /* @escapeNotVerified */ echo __('RSS Feed') ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index ac90dfb31af..c8045ccdcf1 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -14,12 +14,12 @@ <form class="form shared wishlist" action="<?php echo $block->escapeUrl($block->getUrl('wishlist/index/update')) ?>" method="post"> <div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> - <caption class="table-caption"><?php /* @noEscape */ echo __('Wish List'); ?></caption> + <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Wish List'); ?></caption> <thead> <tr> - <th class="col product" scope="col"><?php /* @noEscape */ echo __('Product') ?></th> - <th class="col comment" scope="col"><?php /* @noEscape */ echo __('Comment') ?></th> - <th class="col actions" scope="col"><?php /* @noEscape */ echo __('Add to Cart') ?></th> + <th class="col product" scope="col"><?php /* @escapeNotVerified */ echo __('Product') ?></th> + <th class="col comment" scope="col"><?php /* @escapeNotVerified */ echo __('Comment') ?></th> + <th class="col actions" scope="col"><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></th> </tr> </thead> <tbody> @@ -30,7 +30,7 @@ ?> <tr> <td data-th="<?php echo $block->escapeHtml(__('Product')) ?>" class="col product"> - <a class="product photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> + <a class="product photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtmlAttr($product->getName()) ?>"> <?php echo $block->getImage($product, 'customer_shared_wishlist')->toHtml(); ?> </a> <strong class="product name"> @@ -53,15 +53,15 @@ <?php if ($product->isSaleable()): ?> <?php if ($isVisibleProduct): ?> <button type="button" - title="<?php /* @noEscape */ echo __('Add to Cart') ?>" + title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>" data-post='<?php /* @noEscape */ echo $block->getSharedItemAddToCartUrl($item); ?>' class="action tocart"> - <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> <?php endif ?> <?php endif; ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> - <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> </a> </td> </tr> @@ -74,20 +74,20 @@ <?php if ($block->isSaleable()):?> <div class="primary"> <button type="button" - title="<?php /* @noEscape */ echo __('Add All to Cart') ?>" + title="<?php /* @escapeNotVerified */ echo __('Add All to Cart') ?>" data-post='<?php echo $block->escapeUrl($block->getSharedAddAllToCartUrl()); ?>' class="action tocart primary"> - <span><?php /* @noEscape */ echo __('Add All to Cart') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Add All to Cart') ?></span> </button> </div> <?php endif;?> <div class="secondary"> <a href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>" class="action back"> - <span><?php /* @noEscape */ echo __('Back') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> </a> </div> </div> </form> <?php else: ?> - <div class="message info empty"><div><?php /* @noEscape */ echo __('Wish List is empty now.') ?></div></div> + <div class="message info empty"><div><?php /* @escapeNotVerified */ echo __('Wish List is empty now.') ?></div></div> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index d2c7619a826..5ffe6c892e5 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -13,29 +13,29 @@ action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" id="form-validate" method="post" - data-hasrequired="<?php /* @noEscape */ echo __('* Required Fields') ?>" + data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" data-mage-init='{"validation":{}}'> <fieldset class="fieldset"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @noEscape */ echo __('Sharing Information') ?></span></legend><br /> + <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Sharing Information') ?></span></legend><br /> <div class="field emails required"> - <label class="label" for="email_address"><span><?php /* @noEscape */ echo __('Email addresses, separated by commas') ?></span></label> + <label class="label" for="email_address"><span><?php /* @escapeNotVerified */ echo __('Email addresses, separated by commas') ?></span></label> <div class="control"> <textarea name="emails" cols="60" rows="5" id="email_address" data-validate="{required:true,'validate-emails':true}"><?php /* @noEscape */ echo $block->getEnteredData('emails') ?></textarea> </div> </div> <div class="field text"> - <label class="label" for="message"><span><?php /* @noEscape */ echo __('Message') ?></span></label> + <label class="label" for="message"><span><?php /* @escapeNotVerified */ echo __('Message') ?></span></label> <div class="control"> <textarea id="message" name="message" cols="60" rows="5"><?php /* @noEscape */ echo $block->getEnteredData('message') ?></textarea> </div> </div> <?php if ($this->helper('Magento\Wishlist\Helper\Rss')->isRssAllow()): ?> <div class="field choice rss"> - <input type="checkbox" name="rss_url" id="rss_url" value="1" title="<?php /* @noEscape */ echo __('Check here to link an RSS feed to your Wish List.') ?>" class="checkbox"> + <input type="checkbox" name="rss_url" id="rss_url" value="1" title="<?php /* @escapeNotVerified */ echo __('Check here to link an RSS feed to your Wish List.') ?>" class="checkbox"> <label class="label" for="rss_url"> <span> - <?php /* @noEscape */ echo __('Check here to link an RSS feed to your Wish List.') ?> + <?php /* @escapeNotVerified */ echo __('Check here to link an RSS feed to your Wish List.') ?> </span> </label> </div> @@ -43,12 +43,12 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" title="<?php /* @noEscape */ echo __('Share Wish List') ?>" class="action submit primary"> - <span><?php /* @noEscape */ echo __('Share Wish List') ?></span> + <button type="submit" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action submit primary"> + <span><?php /* @escapeNotVerified */ echo __('Share Wish List') ?></span> </button> </div> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"><span><?php /* @noEscape */ echo __('Back')?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"><span><?php /* @escapeNotVerified */ echo __('Back')?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml index 465662c2bc1..39cbb16d837 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml @@ -15,13 +15,13 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <?php if ($wishlistHelper->isAllow()) : ?> <div class="block block-wishlist" data-bind="scope: 'wishlist'"> <div class="block-title"> - <strong role="heading" aria-level="2"><?php /* @noEscape */ echo $block->getTitle(); ?></strong> + <strong role="heading" aria-level="2"><?php echo $block->escapeHtml($block->getTitle()); ?></strong> <!-- ko if: wishlist().counter --> <span data-bind="text: wishlist().counter" class="counter"></span> <!-- /ko --> </div> <div class="block-content"> - <strong class="subtitle"><?php /* @noEscape */ echo __('Last Added Items') ?></strong> + <strong class="subtitle"><?php /* @escapeNotVerified */ echo __('Last Added Items') ?></strong> <!-- ko if: wishlist().counter --> <ol class="product-items no-display" id="wishlist-sidebar" data-bind="foreach: wishlist().items, css: {'no-display': null}"> <li class="product-item"> @@ -40,18 +40,18 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <!-- ko if: product_is_saleable_and_visible --> <div class="actions-primary"> <!-- ko if: product_has_required_options --> - <a href="#" data-bind="attr: {'data-post': add_to_cart_params}" class="action tocart primary"><span><?php /* @noEscape */ echo __('Add to Cart') ?></span></a> + <a href="#" data-bind="attr: {'data-post': add_to_cart_params}" class="action tocart primary"><span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span></a> <!-- /ko --> <!-- ko ifnot: product_has_required_options --> - <button type="button" class="action tocart primary" data-bind="attr: {'data-post': add_to_cart_params}"><span><?php /* @noEscape */ echo __('Add to Cart') ?></span></button> + <button type="button" class="action tocart primary" data-bind="attr: {'data-post': add_to_cart_params}"><span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span></button> <!-- /ko --> </div> <!-- /ko --> <div class="actions-secondary"> <a href="#" data-bind="attr: {'data-post': delete_item_params}" - title="<?php /* @noEscape */ echo __('Remove This Item') ?>" + title="<?php /* @escapeNotVerified */ echo __('Remove This Item') ?>" class="btn-remove action delete"> - <span><?php /* @noEscape */ echo __('Remove This Item') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Remove This Item') ?></span> </a> </div> </div> @@ -63,12 +63,12 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <div class="primary"> <a class="action details" href="<?php echo $block->escapeUrl($this->helper('Magento\Wishlist\Helper\Data')->getListUrl()) ?>" - title="<?php /* @noEscape */ echo __('Go to Wish List') ?>"><span><?php /* @noEscape */ echo __('Go to Wish List') ?></span></a> + title="<?php /* @escapeNotVerified */ echo __('Go to Wish List') ?>"><span><?php /* @escapeNotVerified */ echo __('Go to Wish List') ?></span></a> </div> </div> <!-- /ko --> <!-- ko ifnot: wishlist().counter --> - <div class="empty"><?php /* @noEscape */ echo __('You have no items in your wish list.') ?></div> + <div class="empty"><?php /* @escapeNotVerified */ echo __('You have no items in your wish list.') ?></div> <!-- /ko --> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml index 3ef71a66825..03aa0707507 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml @@ -24,7 +24,7 @@ <?php $block->getChildBlock('items')->setItems($block->getWishlistItems()); ?> <?php echo $block->getChildHtml('items');?> <?php else: ?> - <div class="message info empty"><span><?php /* @noEscape */ echo __('You have no items in your wish list.') ?></span></div> + <div class="message info empty"><span><?php /* @escapeNotVerified */ echo __('You have no items in your wish list.') ?></span></div> <?php endif ?> <?php echo $block->getChildHtml('bottom'); ?> <div class="actions-toolbar"> @@ -33,7 +33,7 @@ </div> <div class="secondary"> <a href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>" class="action back"> - <span><?php /* @noEscape */ echo __('Back') ?></span> + <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> </a> </div> </div> -- GitLab From a66fac7add7bd11edff573cc157f8c7ffbd7fb95 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Wed, 3 Aug 2016 12:39:28 +0300 Subject: [PATCH 110/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../Api/ProductRepositoryInterfaceTest.php | 74 ++++++++++- .../Catalog/_files/products_for_search.php | 122 ++++++++++++++++++ .../_files/products_for_search_rollback.php | 36 ++++++ 3 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search_rollback.php diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index ae6a0361abd..c42621b29d3 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -6,11 +6,15 @@ namespace Magento\Catalog\Api; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Catalog\Helper\Product; use Magento\Store\Model\Store; use Magento\CatalogInventory\Api\Data\StockItemInterface; use Magento\Store\Model\Website; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; /** @@ -299,7 +303,7 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract $this->setExpectedException('Exception', 'Requested product doesn\'t exist'); // Delete all with 'all' store code - $this->deleteProduct($sku, 'all'); + $this->deleteProduct($sku); $this->getProduct($sku); } @@ -681,6 +685,72 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract $this->assertEquals('simple', $response['items'][0]['sku']); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php + */ + public function testGetListWithMultipleFilterGroupsAndSortingAndPagination() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(ProductInterface::NAME) + ->setValue('search product 2') + ->create(); + $filter2 = $filterBuilder->setField(ProductInterface::NAME) + ->setValue('search product 3') + ->create(); + $filter3 = $filterBuilder->setField(ProductInterface::NAME) + ->setValue('search product 4') + ->create(); + $filter4 = $filterBuilder->setField(ProductInterface::NAME) + ->setValue('search product 5') + ->create(); + $filter5 = $filterBuilder->setField(ProductInterface::PRICE) + ->setValue(35) + ->setConditionType('lt') + ->create(); + $filter6 = $filterBuilder->setField('category_id') + ->setValue(333) + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField('meta_title')->setDirection(SortOrder::SORT_DESC)->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->addFilters([$filter6]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchData = $searchCriteriaBuilder->create()->__toArray(); + $requestData = ['searchCriteria' => $searchData]; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $searchResult = $this->_webApiCall($serviceInfo, $requestData); + + $this->assertEquals(3, $searchResult['total_count']); + $this->assertEquals(1, count($searchResult['items'])); + $this->assertEquals('search_product_4', $searchResult['items'][0][ProductInterface::SKU]); + } + /** * @param $customAttributes * @return array diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php new file mode 100644 index 00000000000..7d676327da6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php @@ -0,0 +1,122 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +include_once 'category.php'; + +use Magento\Catalog\Api\CategoryLinkManagementInterface; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Model\Product\Visibility; + +$products = [ + [ + 'type' => 'simple', + 'id' => 101, + 'name' => 'search product 1', + 'sku' => 'search_product_1', + 'status' => Visibility::VISIBILITY_BOTH, + 'visibility' => Status::STATUS_ENABLED, + 'attribute_set' => 4, + 'website_ids' => [1], + 'price' => 10, + 'category_id' => 333, + 'meta_title' => 'Key Title', + 'meta_keyword' => 'meta keyword', + 'meta_description' => 'meta description', + ], + [ + 'type' => 'simple', + 'id' => 102, + 'name' => 'search product 2', + 'sku' => 'search_product_2', + 'status' => Visibility::VISIBILITY_BOTH, + 'visibility' => Status::STATUS_ENABLED, + 'attribute_set' => 4, + 'website_ids' => [1], + 'price' => 10, + 'category_id' => 333, + 'meta_title' => 'Last Title', + 'meta_keyword' => 'meta keyword', + 'meta_description' => 'meta description', + ], + [ + 'type' => 'simple', + 'id' => 103, + 'name' => 'search product 3', + 'sku' => 'search_product_3', + 'status' => Visibility::VISIBILITY_BOTH, + 'visibility' => Status::STATUS_ENABLED, + 'attribute_set' => 4, + 'website_ids' => [1], + 'price' => 20, + 'category_id' => 333, + 'meta_title' => 'First Title', + 'meta_keyword' => 'meta keyword', + 'meta_description' => 'meta description', + ], + [ + 'type' => 'simple', + 'id' => 104, + 'name' => 'search product 4', + 'sku' => 'search_product_4', + 'status' => Visibility::VISIBILITY_BOTH, + 'visibility' => Status::STATUS_ENABLED, + 'attribute_set' => 4, + 'website_ids' => [1], + 'price' => 30, + 'category_id' => 333, + 'meta_title' => 'A title', + 'meta_keyword' => 'meta keyword', + 'meta_description' => 'meta description', + ], + [ + 'type' => 'simple', + 'id' => 105, + 'name' => 'search product 5', + 'sku' => 'search_product_5', + 'status' => Visibility::VISIBILITY_BOTH, + 'visibility' => Status::STATUS_ENABLED, + 'attribute_set' => 4, + 'website_ids' => [1], + 'price' => 40, + 'category_id' => 333, + 'meta_title' => 'meta title', + 'meta_keyword' => 'meta keyword', + 'meta_description' => 'meta description', + ], +]; + +/** @var CategoryLinkManagementInterface $categoryLinkManagement */ +$categoryLinkManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(CategoryLinkManagementInterface::class); + +$categoriesToAssign = []; + +foreach ($products as $data) { + /** @var $product Product */ + $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(Product::class); + $product + ->setTypeId($data['type']) + ->setId($data['id']) + ->setAttributeSetId($data['attribute_set']) + ->setWebsiteIds($data['website_ids']) + ->setName($data['name']) + ->setSku($data['sku']) + ->setPrice($data['price']) + ->setMetaTitle($data['meta_title']) + ->setMetaKeyword($data['meta_keyword']) + ->setMetaDescription($data['meta_keyword']) + ->setVisibility($data['visibility']) + ->setStatus($data['status']) + ->setStockData(['use_config_manage_stock' => 0]) + ->save(); + + $categoriesToAssign[$data['sku']][] = $data['category_id']; +} + +foreach ($categoriesToAssign as $sku => $categoryIds) { + $categoryLinkManagement->assignProductToCategories($sku, $categoryIds); +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search_rollback.php new file mode 100644 index 00000000000..8c0cf3183eb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search_rollback.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\TestFramework\Helper\Bootstrap; + +Bootstrap::getInstance()->getInstance()->reinitialize(); + +/** @var Registry $registry */ +$registry = Bootstrap::getObjectManager()->get(Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + +$productSkus = ['search_product_1', 'search_product_2', 'search_product_3', 'search_product_4', 'search_product_5']; +foreach ($productSkus as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + $productRepository->delete($product); + } catch (NoSuchEntityException $e) { + + } +} + +include_once 'category_rollback.php'; + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); -- GitLab From fc8edfda117cae81eb4fae9848b24e0973ff8f6a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Wed, 3 Aug 2016 12:40:51 +0300 Subject: [PATCH 111/838] MAGETWO-56081: SearchCriteria Unified Processing for autogenerated repositories --- .../Code/Generator/Repository.php | 71 +++++++++++++++---- .../Generator/_files/SampleRepository.txt | 32 ++++++--- 2 files changed, 81 insertions(+), 22 deletions(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php index c520835f09f..0c825a5ed5a 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php +++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php @@ -8,6 +8,9 @@ namespace Magento\Framework\ObjectManager\Code\Generator; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; + /** * Class Repository */ @@ -82,7 +85,21 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract [ 'name' => 'var', 'description' => - '\\' . \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class, + '\\' . JoinProcessorInterface::class, + ], + ], + ] + ], + [ + 'name' => 'collectionProcessor', + 'visibility' => 'private', + 'docblock' => [ + 'shortDescription' => 'Search Criteria Collection processor.', + 'tags' => [ + [ + 'name' => 'var', + 'description' => + '\\' . CollectionProcessorInterface::class, ], ], ] @@ -154,7 +171,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract ], [ 'name' => 'extensionAttributesJoinProcessor', - 'type' => '\\' . \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class, + 'type' => '\\' . JoinProcessorInterface::class, ], ], 'body' => "\$this->" @@ -175,12 +192,11 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract [ 'name' => 'param', 'description' => $this->_getCollectionFactoryClassName() - . " \$" . $this->_getSourceCollectionFactoryPropertyName() + . " \$" . $this->_getSourceCollectionFactoryPropertyName(), ], [ 'name' => 'param', - 'description' => '\\' . \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class - . " \$extensionAttributesJoinProcessor" + 'description' => '\\' . JoinProcessorInterface::class . " \$extensionAttributesJoinProcessor", ], ], ] @@ -468,14 +484,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract { $body = "\$collection = \$this->" . $this->_getSourceCollectionFactoryPropertyName() . "->create();\n" . "\$this->extensionAttributesJoinProcessor->process(\$collection);\n" - . "foreach (\$searchCriteria->getFilterGroups() as \$filterGroup) {\n" - . " foreach (\$filterGroup->getFilters() as \$filter) {\n" - . " \$condition = \$filter->getConditionType() ? \$filter->getConditionType() : 'eq';\n" - . " \$collection->addFieldToFilter(\$filter->getField(), [\$condition => \$filter->getValue()]);\n" - . " }\n" - . "}\n" - . "\$collection->setCurPage(\$searchCriteria->getCurrentPage());\n" - . "\$collection->setPageSize(\$searchCriteria->getPageSize());\n" + . "\$this->getCollectionProcessor()->process(\$searchCriteria, \$collection);\n" . "return \$collection;\n"; return [ 'name' => 'getList', @@ -502,6 +511,39 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract ]; } + /** + * Returns getList() method + * + * @return string + */ + private function _getGetCollectionProcessorMethod() + { + $body = "if (!\$this->collectionProcessor) {\n" + . " \$this->collectionProcessor = \\Magento\\Framework\\App\\ObjectManager::getInstance()->get(\n" + . " \\" . CollectionProcessorInterface::class . "::class\n" + . " );\n" + . "}\n" + . "return \$this->collectionProcessor;\n"; + return [ + 'name' => 'getCollectionProcessor', + 'visibility' => 'private', + 'parameters' => [], + 'body' => $body, + 'docblock' => [ + 'shortDescription' => 'Retrieve collection processor', + 'tags' => [ + [ + 'name' => 'deprecated', + ], + [ + 'name' => 'return', + 'description' => "\\" . CollectionProcessorInterface::class, + ], + ], + ] + ]; + } + /** * Returns list of methods for class generator * @@ -519,7 +561,8 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract $this->_getDeleteMethod(), $this->_getDeleteByIdMethod(), $this->_getFlushMethod(), - $this->_getSaveMethod() + $this->_getSaveMethod(), + $this->_getGetCollectionProcessorMethod(), ]; } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt index b56cf460275..4ddebf82816 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Code/Generator/_files/SampleRepository.txt @@ -35,6 +35,13 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato */ protected $extensionAttributesJoinProcessor = null; + /** + * Search Criteria Collection processor. + * + * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface + */ + private $collectionProcessor = null; + /** * Repository constructor * @@ -104,14 +111,7 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato { $collection = $this->sampleInterfaceSearchResultFactory->create(); $this->extensionAttributesJoinProcessor->process($collection); - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $this->getCollectionProcessor()->process($searchCriteria, $collection); return $collection; } @@ -172,4 +172,20 @@ class SampleRepository implements \Magento\Framework\ObjectManager\Code\Generato $this->sampleInterfacePersistor->doPersistEntity($entity); return $entity; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } -- GitLab From 555751a04f05e8cc67b46583c70b7a34dfae61a9 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 13:22:56 +0300 Subject: [PATCH 112/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- .../ResourceModel/GroupRepositoryTest.php | 97 +++++++------- .../Magento/Quote/Model/QuoteRepository.php | 46 ++++--- .../Test/Unit/Model/QuoteRepositoryTest.php | 36 ++--- .../JoinProcessor/CalculationData.php | 37 ++++++ .../JoinProcessor/CustomerTaxClass.php | 26 ++++ .../JoinProcessor/ProductTaxClass.php | 26 ++++ .../Api/SearchCriteria/JoinProcessor/Rate.php | 26 ++++ .../Tax/Model/Calculation/RateRepository.php | 45 ++++--- .../Magento/Tax/Model/TaxClass/Repository.php | 45 ++++--- .../Magento/Tax/Model/TaxRuleRepository.php | 57 ++++---- .../Model/Calculation/RateRepositoryTest.php | 41 +++--- .../Unit/Model/TaxClass/RepositoryTest.php | 39 +++--- .../Test/Unit/Model/TaxRuleRepositoryTest.php | 54 ++++---- app/code/Magento/Tax/etc/di.xml | 80 +++++++++++ .../Api/ProductRepositoryInterfaceTest.php | 1 + .../Tax/Api/TaxClassRepositoryTest.php | 17 ++- .../Magento/Tax/Api/TaxRateRepositoryTest.php | 14 +- .../Api/TaxRuleRepositoryInterfaceTest.php | 70 +++++++--- .../CollectionProcessor/JoinProcessor.php | 125 ++++++++++++++++++ .../JoinProcessor/CustomJoinInterface.php | 22 +++ .../CollectionProcessor/JoinProcessorTest.php | 125 ++++++++++++++++++ 21 files changed, 793 insertions(+), 236 deletions(-) create mode 100644 app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CalculationData.php create mode 100644 app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CustomerTaxClass.php create mode 100644 app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/ProductTaxClass.php create mode 100644 app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/Rate.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php create mode 100644 lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor/CustomJoinInterface.php create mode 100644 lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/JoinProcessorTest.php diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php index 1796ce93ff5..1524db8ab97 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/GroupRepositoryTest.php @@ -79,6 +79,57 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase protected $model; protected function setUp() + { + $this->setupGroupObjects(); + $this->dataObjectProcessor = $this->getMock( + \Magento\Framework\Reflection\DataObjectProcessor::class, + [], + [], + '', + false + ); + $this->searchResultsFactory = $this->getMock( + \Magento\Customer\Api\Data\GroupSearchResultsInterfaceFactory::class, + ['create'], + [], + '', + false + ); + $this->searchResults = $this->getMockForAbstractClass( + \Magento\Customer\Api\Data\GroupSearchResultsInterface::class, + [], + '', + false + ); + $this->taxClassRepository = $this->getMockForAbstractClass( + \Magento\Tax\Api\TaxClassRepositoryInterface::class, + [], + '', + false + ); + $this->extensionAttributesJoinProcessor = $this->getMockForAbstractClass( + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class, + [], + '', + false + ); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + + $this->model = new \Magento\Customer\Model\ResourceModel\GroupRepository( + $this->groupRegistry, + $this->groupFactory, + $this->groupDataFactory, + $this->groupResourceModel, + $this->dataObjectProcessor, + $this->searchResultsFactory, + $this->taxClassRepository, + $this->extensionAttributesJoinProcessor, + $this->collectionProcessorMock + ); + } + + private function setupGroupObjects() { $this->groupRegistry = $this->getMock( \Magento\Customer\Model\GroupRegistry::class, @@ -134,52 +185,6 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - $this->dataObjectProcessor = $this->getMock( - \Magento\Framework\Reflection\DataObjectProcessor::class, - [], - [], - '', - false - ); - $this->searchResultsFactory = $this->getMock( - \Magento\Customer\Api\Data\GroupSearchResultsInterfaceFactory::class, - ['create'], - [], - '', - false - ); - $this->searchResults = $this->getMockForAbstractClass( - \Magento\Customer\Api\Data\GroupSearchResultsInterface::class, - [], - '', - false - ); - $this->taxClassRepository = $this->getMockForAbstractClass( - \Magento\Tax\Api\TaxClassRepositoryInterface::class, - [], - '', - false - ); - $this->extensionAttributesJoinProcessor = $this->getMockForAbstractClass( - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class, - [], - '', - false - ); - $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) - ->getMock(); - - $this->model = new \Magento\Customer\Model\ResourceModel\GroupRepository( - $this->groupRegistry, - $this->groupFactory, - $this->groupDataFactory, - $this->groupResourceModel, - $this->dataObjectProcessor, - $this->searchResultsFactory, - $this->taxClassRepository, - $this->extensionAttributesJoinProcessor, - $this->collectionProcessorMock - ); } public function testSave() diff --git a/app/code/Magento/Quote/Model/QuoteRepository.php b/app/code/Magento/Quote/Model/QuoteRepository.php index 427d3313b17..34dad6f0fd0 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository.php +++ b/app/code/Magento/Quote/Model/QuoteRepository.php @@ -5,6 +5,7 @@ */ namespace Magento\Quote\Model; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\NoSuchEntityException; @@ -71,12 +72,16 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface */ private $loadHandler; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * @param QuoteFactory $quoteFactory * @param StoreManagerInterface $storeManager * @param \Magento\Quote\Model\ResourceModel\Quote\Collection $quoteCollection * @param \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory * @param JoinProcessorInterface $extensionAttributesJoinProcessor + * @param CollectionProcessorInterface $collectionProcessor * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( @@ -84,12 +89,14 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface StoreManagerInterface $storeManager, \Magento\Quote\Model\ResourceModel\Quote\Collection $quoteCollection, \Magento\Quote\Api\Data\CartSearchResultsInterfaceFactory $searchResultsDataFactory, - JoinProcessorInterface $extensionAttributesJoinProcessor + JoinProcessorInterface $extensionAttributesJoinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->quoteFactory = $quoteFactory; $this->storeManager = $storeManager; $this->searchResultsDataFactory = $searchResultsDataFactory; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -223,30 +230,14 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface $searchData = $this->searchResultsDataFactory->create(); $searchData->setSearchCriteria($searchCriteria); - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $this->quoteCollection); - } - - $searchData->setTotalCount($this->quoteCollection->getSize()); - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders) { - /** @var SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $this->quoteCollection->addOrder( - $sortOrder->getField(), - $sortOrder->getDirection() == SortOrder::SORT_ASC ? 'ASC' : 'DESC' - ); - } - } - $this->quoteCollection->setCurPage($searchCriteria->getCurrentPage()); - $this->quoteCollection->setPageSize($searchCriteria->getPageSize()); + $this->collectionProcessor->process($searchCriteria, $this->quoteCollection); $this->extensionAttributesJoinProcessor->process($this->quoteCollection); foreach ($this->quoteCollection->getItems() as $quote) { /** @var CartInterface $quote */ $this->getLoadHandler()->load($quote); } $searchData->setItems($this->quoteCollection->getItems()); - + $searchData->setTotalCount($this->quoteCollection->getSize()); return $searchData; } @@ -256,6 +247,7 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface * @param FilterGroup $filterGroup The filter group. * @param QuoteCollection $collection The quote collection. * @return void + * @deprecated * @throws InputException The specified filter group or quote collection does not exist. */ protected function addFilterGroupToCollection(FilterGroup $filterGroup, QuoteCollection $collection) @@ -296,4 +288,20 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface } return $this->loadHandler; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index 462ce8381fd..2679c8c1465 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -61,6 +61,12 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase */ private $loadHandlerMock; + /** + * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface | + * \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -103,7 +109,13 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->model = $objectManager->getObject( \Magento\Quote\Model\QuoteRepository::class, [ @@ -111,7 +123,8 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase 'storeManager' => $this->storeManagerMock, 'searchResultsDataFactory' => $this->searchResultsDataFactory, 'quoteCollection' => $this->quoteCollectionMock, - 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock + 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, + 'collectionProcessor' => $this->collectionProcessor ] ); @@ -402,9 +415,8 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase /** * @param int $direction * @param string $expectedDirection - * @dataProvider getListSuccessDataProvider */ - public function testGetListSuccess($direction, $expectedDirection) + public function testGetListSuccess() { $this->markTestSkipped('MAGETWO-48531'); $searchResult = $this->getMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class, [], [], '', false); @@ -441,21 +453,14 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase ->setMethods(['getField', 'getDirection']) ->disableOriginalConstructor() ->getMock(); - - //foreach cycle - $searchCriteriaMock - ->expects($this->once()) - ->method('getSortOrders') - ->will($this->returnValue([$sortOrderMock])); - $sortOrderMock->expects($this->once())->method('getField')->will($this->returnValue('id')); - $sortOrderMock->expects($this->once())->method('getDirection')->will($this->returnValue($direction)); - $this->quoteCollectionMock->expects($this->once())->method('addOrder')->with('id', $expectedDirection); - + $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->will($this->returnValue(1)); $searchCriteriaMock->expects($this->once())->method('getPageSize')->will($this->returnValue(10)); $this->quoteCollectionMock->expects($this->once())->method('setCurPage')->with(1); $this->quoteCollectionMock->expects($this->once())->method('setPageSize')->with(10); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $this->quoteCollectionMock); $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') ->with( @@ -481,6 +486,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase } /** + * @deprecated * @return array */ public function getListSuccessDataProvider() diff --git a/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CalculationData.php b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CalculationData.php new file mode 100644 index 00000000000..ccbc5876146 --- /dev/null +++ b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CalculationData.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Tax\Model\Api\SearchCriteria\JoinProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * Class CalculationData + * @package Magento\Tax\Model\Api\SearchCriteria\JoinProcessor + */ +class CalculationData implements CustomJoinInterface +{ + /** Alias of table, that will be joined */ + const CALCULATION_DATA_ALIAS = "cd"; + + /** + * @param \Magento\Tax\Model\ResourceModel\Calculation\Rule\Collection $collection + * @return bool + */ + public function apply(AbstractDb $collection) + { + $isNotApplied = !array_key_exists( + self::CALCULATION_DATA_ALIAS, + $collection->getSelect()->getPart(\Magento\Framework\Db\Select::FROM) + ); + if ($isNotApplied) { + $collection->joinCalculationData(self::CALCULATION_DATA_ALIAS); + return true; + } + + return false; + } +} diff --git a/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CustomerTaxClass.php b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CustomerTaxClass.php new file mode 100644 index 00000000000..d7ea765b81e --- /dev/null +++ b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/CustomerTaxClass.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Tax\Model\Api\SearchCriteria\JoinProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * Class CustomerTaxClass + * @package Magento\Tax\Model\Api\SearchCriteria\JoinProcessor + */ +class CustomerTaxClass implements CustomJoinInterface +{ + /** + * @param \Magento\Tax\Model\ResourceModel\Calculation\Rule\Collection $collection + * @return true + */ + public function apply(AbstractDb $collection) + { + $collection->joinCalculationData('ctc'); + return true; + } +} diff --git a/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/ProductTaxClass.php b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/ProductTaxClass.php new file mode 100644 index 00000000000..4245013599e --- /dev/null +++ b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/ProductTaxClass.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Tax\Model\Api\SearchCriteria\JoinProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * Class ProductTaxClass + * @package Magento\Tax\Model\Api\SearchCriteria\JoinProcessor + */ +class ProductTaxClass implements CustomJoinInterface +{ + /** + * @param \Magento\Tax\Model\ResourceModel\Calculation\Rule\Collection $collection + * @return true + */ + public function apply(AbstractDb $collection) + { + $collection->joinCalculationData('ptc'); + return true; + } +} diff --git a/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/Rate.php b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/Rate.php new file mode 100644 index 00000000000..f77ad5fd86b --- /dev/null +++ b/app/code/Magento/Tax/Model/Api/SearchCriteria/JoinProcessor/Rate.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Tax\Model\Api\SearchCriteria\JoinProcessor; + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * Class Rate + * @package Magento\Tax\Model\Api\SearchCriteria\JoinProcessor + */ +class Rate implements CustomJoinInterface +{ + /** + * @param \Magento\Tax\Model\ResourceModel\Calculation\Rule\Collection $collection + * @return true + */ + public function apply(AbstractDb $collection) + { + $collection->joinCalculationData('rate'); + return true; + } +} diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index b2d63d99dc8..e7531547e2a 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -10,6 +10,7 @@ namespace Magento\Tax\Model\Calculation; use Magento\Directory\Model\CountryFactory; use Magento\Directory\Model\RegionFactory; use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; @@ -68,6 +69,9 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface */ protected $joinProcessor; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * @param Converter $converter * @param RateRegistry $rateRegistry @@ -77,6 +81,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface * @param RegionFactory $regionFactory * @param \Magento\Tax\Model\ResourceModel\Calculation\Rate $rateResource * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( Converter $converter, @@ -86,7 +91,8 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface CountryFactory $countryFactory, RegionFactory $regionFactory, \Magento\Tax\Model\ResourceModel\Calculation\Rate $rateResource, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, + CollectionProcessorInterface $collectionProcessor ) { $this->converter = $converter; $this->rateRegistry = $rateRegistry; @@ -96,6 +102,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface $this->regionFactory = $regionFactory; $this->resourceModel = $rateResource; $this->joinProcessor = $joinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -155,24 +162,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface $this->joinProcessor->process($collection); $collection->joinRegionTable(); - //Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - - $sortOrders = $searchCriteria->getSortOrders(); - /** @var SortOrder $sortOrder */ - if ($sortOrders) { - foreach ($sortOrders as $sortOrder) { - $collection->addOrder( - $this->translateField($sortOrder->getField()), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); - + $this->collectionProcessor->process($searchCriteria, $collection); $taxRate = []; /** @var \Magento\Tax\Model\Calculation\Rate $taxRateModel */ @@ -192,6 +182,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface * @param FilterGroup $filterGroup * @param Collection $collection * @return void + * @deprecated * @throws \Magento\Framework\Exception\InputException */ protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) @@ -308,4 +299,20 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface throw $exception; } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Tax/Model/TaxClass/Repository.php b/app/code/Magento/Tax/Model/TaxClass/Repository.php index 30fade99f50..880cc74dc3c 100644 --- a/app/code/Magento/Tax/Model/TaxClass/Repository.php +++ b/app/code/Magento/Tax/Model/TaxClass/Repository.php @@ -9,6 +9,7 @@ namespace Magento\Tax\Model\TaxClass; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\CouldNotDeleteException; @@ -66,6 +67,9 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface */ protected $joinProcessor; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param FilterBuilder $filterBuilder @@ -74,6 +78,7 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface * @param ClassModelRegistry $classModelRegistry * @param \Magento\Tax\Model\ResourceModel\TaxClass $taxClassResource * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( SearchCriteriaBuilder $searchCriteriaBuilder, @@ -82,7 +87,8 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface \Magento\Tax\Api\Data\TaxClassSearchResultsInterfaceFactory $searchResultsFactory, ClassModelRegistry $classModelRegistry, \Magento\Tax\Model\ResourceModel\TaxClass $taxClassResource, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->filterBuilder = $filterBuilder; @@ -91,6 +97,7 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface $this->classModelRegistry = $classModelRegistry; $this->taxClassResource = $taxClassResource; $this->joinProcessor = $joinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -203,34 +210,18 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface /** @var TaxClassCollection $collection */ $collection = $this->taxClassCollectionFactory->create(); $this->joinProcessor->process($collection); - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } + $this->collectionProcessor->process($searchCriteria, $collection); $searchResults->setTotalCount($collection->getSize()); - $sortOrders = $searchCriteria->getSortOrders(); - /** @var SortOrder $sortOrder */ - if ($sortOrders) { - foreach ($searchCriteria->getSortOrders() as $sortOrder) { - $collection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); $searchResults->setItems($collection->getItems()); return $searchResults; } /** * Helper function that adds a FilterGroup to the collection. - * - * TODO: This method duplicates functionality of search methods in other services and should be refactored. - * * @param FilterGroup $filterGroup * @param TaxClassCollection $collection * @return void + * @deprecated */ protected function addFilterGroupToCollection(FilterGroup $filterGroup, TaxClassCollection $collection) { @@ -245,4 +236,20 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface $collection->addFieldToFilter($fields, $conditions); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php index b63a1aef1dd..51800ae71c4 100644 --- a/app/code/Magento/Tax/Model/TaxRuleRepository.php +++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php @@ -7,7 +7,7 @@ namespace Magento\Tax\Model; use Magento\Framework\Api\Search\FilterGroup; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\NoSuchEntityException; @@ -56,6 +56,11 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface */ protected $joinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param TaxRuleRegistry $taxRuleRegistry * @param TaxRuleSearchResultsInterfaceFactory $searchResultsFactory @@ -63,6 +68,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface * @param CollectionFactory $collectionFactory * @param ResourceRule $resource * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + * @param CollectionProcessorInterface | null $collectionProcessor */ public function __construct( TaxRuleRegistry $taxRuleRegistry, @@ -70,7 +76,8 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface RuleFactory $ruleFactory, CollectionFactory $collectionFactory, ResourceRule $resource, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->taxRuleRegistry = $taxRuleRegistry; $this->taxRuleSearchResultsFactory = $searchResultsFactory; @@ -78,6 +85,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface $this->collectionFactory = $collectionFactory; $this->resource = $resource; $this->joinProcessor = $joinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -137,35 +145,10 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface { $searchResults = $this->taxRuleSearchResultsFactory->create(); $searchResults->setSearchCriteria($searchCriteria); - - $fields = []; $collection = $this->collectionFactory->create(); $this->joinProcessor->process($collection); - - //Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - foreach ($group->getFilters() as $filter) { - $fields[] = $this->translateField($filter->getField()); - } - } - if ($fields) { - if (in_array('cd.customer_tax_class_id', $fields) || in_array('cd.product_tax_class_id', $fields)) { - $collection->joinCalculationData('cd'); - } - } - + $this->collectionProcessor->process($searchCriteria, $collection); $searchResults->setTotalCount($collection->getSize()); - $sortOrders = $searchCriteria->getSortOrders(); - /** @var SortOrder $sortOrder */ - if ($sortOrders) { - foreach ($sortOrders as $sortOrder) { - $collection->addOrder( - $this->translateField($sortOrder->getField()), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } $collection->setCurPage($searchCriteria->getCurrentPage()); $collection->setPageSize($searchCriteria->getPageSize()); @@ -179,6 +162,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface * @param FilterGroup $filterGroup * @param Collection $collection * @return void + * @deprecated * @throws \Magento\Framework\Exception\InputException */ protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) @@ -213,6 +197,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface * Translates a field name to a DB column name for use in collection queries. * * @param string $field a field name that should be translated to a DB column name. + * @deprecated * @return string */ protected function translateField($field) @@ -232,4 +217,20 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface return $field; } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php index 949b5e18754..b60ce0a7fbc 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php @@ -13,6 +13,8 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\AlreadyExistsException; /** + * Class RateRepositoryTest + * @package Magento\Tax\Test\Unit\Model\Calculation * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class RateRepositoryTest extends \PHPUnit_Framework_TestCase @@ -67,6 +69,12 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase */ private $joinProcessorMock; + /** + * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface + * | \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $this->rateConverterMock = $this->getMock( @@ -132,6 +140,13 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->model = new RateRepository( $this->rateConverterMock, $this->rateRegistryMock, @@ -140,7 +155,8 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase $this->countryFactoryMock, $this->regionFactoryMock, $this->rateResourceMock, - $this->joinProcessorMock + $this->joinProcessorMock, + $this->collectionProcessor ); } @@ -243,12 +259,7 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $searchCriteriaMock->expects($this->any())->method('getFilterGroups')->will($this->returnValue([])); - $searchCriteriaMock->expects($this->any())->method('getSortOrders')->will($this->returnValue([])); - $currentPage = 1; - $pageSize = 100; - $searchCriteriaMock->expects($this->any())->method('getCurrentPage')->will($this->returnValue($currentPage)); - $searchCriteriaMock->expects($this->any())->method('getPageSize')->will($this->returnValue($pageSize)); + $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); $rateMock = $this->getTaxRateMock([]); $objectManager = new ObjectManager($this); @@ -258,8 +269,6 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase $items ); $collectionMock->expects($this->once())->method('joinRegionTable'); - $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); - $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); $collectionMock->expects($this->once())->method('getSize')->will($this->returnValue(count($items))); $this->rateFactoryMock->expects($this->once())->method('create')->will($this->returnValue($rateMock)); @@ -270,6 +279,9 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase ->willReturnSelf(); $this->searchResultMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock) ->willReturnSelf(); + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultMock); $this->joinProcessorMock->expects($this->once())->method('process')->with($collectionMock); @@ -364,6 +376,7 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetListWhenFilterGroupExists() { + $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); $searchCriteriaMock @@ -382,10 +395,6 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase \Magento\Tax\Model\ResourceModel\Calculation\Rate\Collection::class, $items ); - $collectionMock - ->expects($this->once()) - ->method('addFieldToFilter') - ->with(['region_table.code'], [['like' => 'condition_value']]); $sortOrderMock = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); $searchCriteriaMock ->expects($this->any()) @@ -399,10 +408,10 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase $searchCriteriaMock->expects($this->any())->method('getCurrentPage')->will($this->returnValue($currentPage)); $searchCriteriaMock->expects($this->any())->method('getPageSize')->will($this->returnValue($pageSize)); $rateMock = $this->getTaxRateMock([]); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $collectionMock->expects($this->once())->method('joinRegionTable'); - $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); - $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); $collectionMock->expects($this->once())->method('getSize')->will($this->returnValue(count($items))); $this->rateFactoryMock->expects($this->once())->method('create')->will($this->returnValue($rateMock)); diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php index 4a41d04fe7a..11a4fd40b56 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php @@ -55,6 +55,12 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase */ protected $extensionAttributesJoinProcessorMock; + /** + * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface | + * \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * @return void */ @@ -107,7 +113,13 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->model = $this->objectManager->getObject( \Magento\Tax\Model\TaxClass\Repository::class, [ @@ -115,7 +127,8 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase 'taxClassResource' => $this->taxClassResourceMock, 'searchResultsFactory' => $this->searchResultFactory, 'taxClassCollectionFactory' => $this->taxClassCollectionFactory, - 'joinProcessor' => $this->extensionAttributesJoinProcessorMock + 'joinProcessor' => $this->extensionAttributesJoinProcessorMock, + 'collectionProcessor' => $this->collectionProcessor ] ); } @@ -206,34 +219,18 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase $taxClassOne = $this->getMock(\Magento\Tax\Api\Data\TaxClassInterface::class); $taxClassTwo = $this->getMock(\Magento\Tax\Api\Data\TaxClassInterface::class); $searchCriteria = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $filterGroup = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filter = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); $collection = $this->getMock(\Magento\Tax\Model\ResourceModel\TaxClass\Collection::class, [], [], '', false); - $sortOrder = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') ->with($collection); - - $searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]); - $filterGroup->expects($this->once())->method('getFilters')->willReturn([$filter]); - $filter->expects($this->atLeastOnce())->method('getConditionType')->willReturn('eq'); - $filter->expects($this->once())->method('getField')->willReturn('field'); - $filter->expects($this->once())->method('getValue')->willReturn('value'); - $collection->expects($this->once())->method('addFieldToFilter')->with(['field'], [['eq' => 'value']]); - - $searchCriteria->expects($this->exactly(2))->method('getSortOrders')->willReturn([$sortOrder]); - $sortOrder->expects($this->once())->method('getField')->willReturn('field'); - $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC); - $collection->expects($this->once())->method('addOrder')->with('field', 'ASC'); - $searchCriteria->expects($this->once())->method('getPageSize')->willReturn(20); - $searchCriteria->expects($this->once())->method('getCurrentPage')->willReturn(0); + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $collection->expects($this->any())->method('getSize')->willReturn(2); $collection->expects($this->any())->method('setItems')->with([$taxClassOne, $taxClassTwo]); $collection->expects($this->any())->method('getItems')->willReturn([$taxClassOne, $taxClassTwo]); - $collection->expects($this->once())->method('setCurPage')->with(0); - $collection->expects($this->once())->method('setPageSize')->with(20); $this->searchResultMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteria); $this->searchResultMock->expects($this->once())->method('setTotalCount')->with(2); diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php index 773b12a382c..a0f53d82923 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php @@ -9,6 +9,8 @@ use Magento\Framework\Api\SortOrder; use \Magento\Tax\Model\TaxRuleRepository; /** + * Class TaxRuleRepositoryTest + * @package Magento\Tax\Test\Unit\Model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase @@ -58,9 +60,17 @@ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $objectManager; + /** + * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface | + * \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->taxRuleRegistry = + $this->getMock(\Magento\Tax\Model\Calculation\TaxRuleRegistry::class, [], [], '', false); $this->taxRuleRegistry = $this->getMock( \Magento\Tax\Model\Calculation\TaxRuleRegistry::class, [], @@ -98,14 +108,21 @@ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->model = new TaxRuleRepository( $this->taxRuleRegistry, $this->searchResultFactory, $this->ruleFactory, $this->collectionFactory, $this->resource, - $this->extensionAttributesJoinProcessorMock + $this->extensionAttributesJoinProcessorMock, + $this->collectionProcessor ); } @@ -189,44 +206,19 @@ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $collectionSize = 1; - $currentPage = 42; - $pageSize = 4; - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); $collectionMock = $this->getMock(\Magento\Tax\Model\ResourceModel\Calculation\Rule\Collection::class, [], [], '', false); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $sortOrderMock = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); + $this->getMock(\Magento\Tax\Model\ResourceModel\Calculation\Rule\Collection::class, [], [], '', false); $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') ->with($collectionMock); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $this->searchResultsMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock); $this->collectionFactory->expects($this->once())->method('create')->willReturn($collectionMock); - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]); - $filterGroupMock->expects($this->exactly(2))->method('getFilters')->willReturn([$filterMock]); - $filterMock->expects($this->exactly(2))->method('getConditionType')->willReturn('eq'); - $filterMock->expects($this->exactly(2))->method('getField')->willReturnOnConsecutiveCalls( - 'rate.tax_calculation_rate_id', - 'cd.customer_tax_class_id' - ); - $filterMock->expects($this->once())->method('getValue')->willReturn('value'); - $collectionMock->expects($this->exactly(2))->method('joinCalculationData')->withConsecutive(['rate'], ['cd']); - $collectionMock->expects($this->once())->method('addFieldToFilter') - ->with([0 => 'rate.tax_calculation_rate_id'], [0 => ['eq' => 'value']]); - $collectionMock->expects($this->once())->method('getSize')->willReturn($collectionSize); - $this->searchResultsMock->expects($this->once())->method('setTotalCount')->with($collectionSize); - $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]); - $sortOrderMock->expects($this->once())->method('getField')->willReturn('sort_order'); - $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC); - $collectionMock->expects($this->once())->method('addOrder')->with('position', 'ASC'); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); $collectionMock->expects($this->once())->method('getItems')->willReturn([]); $this->searchResultsMock->expects($this->once())->method('setItems')->with([]); $this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultsMock); diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 09f969423f7..01121b3ac2b 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -85,4 +85,84 @@ <argument name="connectionName" xsi:type="string">sales</argument> </arguments> </type> + <type name="Magento\Tax\Model\TaxRuleRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite</argument> + </arguments> + </type> + <type name="Magento\Tax\Model\Calculation\RateRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessorComposite</argument> + </arguments> + </type> + <virtualType name="Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Tax\Model\TaxRate\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Tax\Model\TaxRate\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="tax_calculation_rate_id" xsi:type="string">main_table.tax_calculation_rate_id</item> + <item name="tax_country_id" xsi:type="string">main_table.tax_country_id</item> + <item name="tax_region_id" xsi:type="string">main_table.tax_region_id</item> + <item name="code" xsi:type="string">main_table.code</item> + <item name="rate" xsi:type="string">main_table.rate</item> + <item name="zip_is_range" xsi:type="string">main_table.zip_is_range</item> + <item name="zip_from" xsi:type="string">main_table.zip_from</item> + <item name="zip_to" xsi:type="string">main_table.zip_to</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\JoinProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor"> + <arguments> + <argument name="customJoins" xsi:type="array"> + <item name="rate.tax_calculation_rate_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\Rate</item> + <item name="ctc.customer_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CustomerTaxClass</item> + <item name="ptc.product_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\ProductTaxClass</item> + <item name="cd.customer_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CalculationData</item> + <item name="cd.product_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CalculationData</item> + </argument> + <argument name="fieldMapping" xsi:type="array"> + <item name="id" xsi:type="string">tax_calculation_rule_id</item> + <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> + <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> + <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\SortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> + <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="id" xsi:type="string">tax_calculation_rule_id</item> + <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> + <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> + <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="id" xsi:type="string">tax_calculation_rule_id</item> + <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> + <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> + <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="joins" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\JoinProcessor</item> + <item name="sorting" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index c42621b29d3..f30c1bffa00 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -19,6 +19,7 @@ use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; /** * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ProductRepositoryInterfaceTest extends WebapiAbstract { diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php index 8035900a22d..0c17ed53956 100644 --- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php @@ -10,6 +10,7 @@ namespace Magento\Tax\Api; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Tax\Api\Data\TaxClassInterfaceFactory; use Magento\Tax\Model\ClassModel; @@ -19,6 +20,7 @@ use Magento\TestFramework\TestCase\WebapiAbstract; /** * Tests for tax class service. + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TaxClassRepositoryTest extends WebapiAbstract { @@ -32,6 +34,9 @@ class TaxClassRepositoryTest extends WebapiAbstract /** @var FilterBuilder */ private $filterBuilder; + /** @var SortOrderBuilder */ + private $sortOrderBuilder; + /** @var TaxClassInterfaceFactory */ private $taxClassFactory; @@ -64,6 +69,9 @@ class TaxClassRepositoryTest extends WebapiAbstract \Magento\Tax\Model\TaxClass\Repository::class, ['classModelRegistry' => $this->taxClassRegistry] ); + $this->sortOrderBuilder = Bootstrap::getObjectManager()->create( + \Magento\Framework\Api\SortOrderBuilder::class + ); } /** @@ -268,6 +276,8 @@ class TaxClassRepositoryTest extends WebapiAbstract $filter4 = $this->filterBuilder->setField(ClassModel::KEY_TYPE) ->setValue($customerTaxClass[ClassModel::KEY_TYPE]) ->create(); + $sortOrder = $this->sortOrderBuilder->setField("class_type") + ->setDirection("ASC")->create(); /** * (class_name == 'Retail Customer' || class_name == 'Taxable Goods) @@ -275,6 +285,7 @@ class TaxClassRepositoryTest extends WebapiAbstract */ $this->searchCriteriaBuilder->addFilters([$filter1, $filter2]); $this->searchCriteriaBuilder->addFilters([$filter3, $filter4]); + $this->searchCriteriaBuilder->addSortOrder($sortOrder); $searchCriteria = $this->searchCriteriaBuilder->setCurrentPage(1)->setPageSize(10)->create(); $searchData = $searchCriteria->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -291,15 +302,15 @@ class TaxClassRepositoryTest extends WebapiAbstract ]; $searchResults = $this->_webApiCall($serviceInfo, $requestData); $this->assertEquals(2, $searchResults['total_count']); + $this->assertEquals( - $productTaxClass[ClassModel::KEY_NAME], + $customerTaxClass[ClassModel::KEY_NAME], $searchResults['items'][0][ClassModel::KEY_NAME] ); $this->assertEquals( - $customerTaxClass[ClassModel::KEY_NAME], + $productTaxClass[ClassModel::KEY_NAME], $searchResults['items'][1][ClassModel::KEY_NAME] ); - /** class_name == 'Retail Customer' && ( class_type == 'CUSTOMER' || class_type == 'PRODUCT') */ $this->searchCriteriaBuilder->addFilters([$filter2]); $this->searchCriteriaBuilder->addFilters([$filter3, $filter4]); diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php index 4115db42dd8..54598a603fd 100644 --- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php @@ -479,16 +479,26 @@ class TaxRateRepositoryTest extends WebapiAbstract $this->_markTestAsRestOnly(); $rates = $this->setupTaxRatesForSearch(); + $filterBR = $this->filterBuilder->setField(Rate::KEY_COUNTRY_ID) + ->setValue('BR') + ->create(); + $filterUS = $this->filterBuilder->setField(Rate::KEY_COUNTRY_ID) + ->setValue('US') + ->create(); // Find rates which country id 'CZ' - $filter = $this->filterBuilder->setField(Rate::KEY_COUNTRY_ID) + $filterCZ = $this->filterBuilder->setField(Rate::KEY_COUNTRY_ID) ->setValue('CZ') ->create(); $sortOrder = $this->sortOrderBuilder ->setField(Rate::KEY_POSTCODE) ->setDirection(SortOrder::SORT_DESC) ->create(); + $filterRate = $this->filterBuilder->setField(Rate::KEY_PERCENTAGE_RATE) + ->setValue('2.2000') + ->create(); + $this->searchCriteriaBuilder->addFilters([$filterBR, $filterUS, $filterCZ]); // Order them by descending postcode (not the default order) - $this->searchCriteriaBuilder->addFilters([$filter]) + $this->searchCriteriaBuilder->addFilters([$filterCZ, $filterRate]) ->addSortOrder($sortOrder); $searchData = $this->searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php index dad1f3c493e..ee352a5fa80 100644 --- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php @@ -8,10 +8,16 @@ namespace Magento\Tax\Api; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; use Magento\Webapi\Model\Rest\Config as HttpConstants; +/** + * Class TaxRuleRepositoryInterfaceTest + * @package Magento\Tax\Api + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class TaxRuleRepositoryInterfaceTest extends WebapiAbstract { const SERVICE_NAME = "taxTaxRuleRepositoryV1"; @@ -33,6 +39,15 @@ class TaxRuleRepositoryInterfaceTest extends WebapiAbstract /** @var SearchCriteriaBuilder */ private $searchCriteriaBuilder; + /** @var \Magento\Tax\Api\Data\TaxClassInterface | \Magento\Tax\Model\ClassModel */ + private $taxClass; + + /** @var \Magento\Tax\Api\Data\TaxRateInterface | \Magento\Tax\Model\Calculation\Rate */ + private $taxRate; + + /** @var SortOrderBuilder */ + private $sortOrderBuilder; + /** * Execute per test initialization. */ @@ -52,6 +67,16 @@ class TaxRuleRepositoryInterfaceTest extends WebapiAbstract $this->filterBuilder = $objectManager->create( \Magento\Framework\Api\FilterBuilder::class ); + $this->sortOrderBuilder = $objectManager->create( + SortOrderBuilder::class + ); + $this->taxClass = $objectManager->create( + \Magento\Tax\Api\Data\TaxClassInterface::class + ); + + $this->taxRate = $objectManager->create( + \Magento\Tax\Api\Data\TaxRateInterface::class + ); /** Initialize tax classes, tax rates and tax rules defined in fixture Magento/Tax/_files/tax_classes.php */ $this->getFixtureTaxRates(); @@ -311,21 +336,32 @@ class TaxRuleRepositoryInterfaceTest extends WebapiAbstract /** * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php */ - public function testSearchTaxRulesCodeLike() + public function testSearchTaxRulesCodeWithJoins() { - // Find rules whose code starts with 'Test Rule' - $filter = $this->filterBuilder - ->setField('code') - ->setValue('Test Rule%') - ->setConditionType('like') - ->create(); + $customerTaxClass = clone $this->taxClass->load('CustomerTaxClass2', 'class_name'); + $productTaxClass = clone $this->taxClass->load('Taxable Goods', 'class_name'); + $taxRate = $this->taxRate->load('*', 'code'); - $sortFilter = $this->filterBuilder - ->setField('position') - ->setValue(0) + $filter2 = $this->filterBuilder + ->setField('cd.customer_tax_class_id') + ->setValue($customerTaxClass->getClassId()) + ->create(); + $filter3 = $this->filterBuilder + ->setField('ptc.product_tax_class_id') + ->setValue($productTaxClass->getClassId()) + ->create(); + $filter4 = $this->filterBuilder + ->setField('rate.tax_calculation_rate_id') + ->setValue($taxRate->getId()) + ->create(); + $sortOrder = $this->sortOrderBuilder + ->setField('code') + ->setDirection('DESC') ->create(); - $this->searchCriteriaBuilder->addFilters([$filter, $sortFilter]); + $this->searchCriteriaBuilder->addFilters([$filter2, $filter3]); + $this->searchCriteriaBuilder->addFilters([$filter4]); + $this->searchCriteriaBuilder->addSortOrder($sortOrder); $fixtureRule = $this->getFixtureTaxRules()[1]; @@ -350,24 +386,24 @@ class TaxRuleRepositoryInterfaceTest extends WebapiAbstract $expectedRuleData = [ [ - 'id' => $fixtureRule->getId(), - 'code' => 'Test Rule', + 'id' => $this->getFixtureTaxRules()[0]->getId(), + 'code' => 'Test Rule Duplicate', 'priority' => 0, 'position' => 0, 'calculate_subtotal' => 0, 'customer_tax_class_ids' => array_values(array_unique($fixtureRule->getCustomerTaxClasses())), 'product_tax_class_ids' => array_values(array_unique($fixtureRule->getProductTaxClasses())), - 'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())), + 'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())) ], [ - 'id' => $this->getFixtureTaxRules()[0]->getId(), - 'code' => 'Test Rule Duplicate', + 'id' => $fixtureRule->getId(), + 'code' => 'Test Rule', 'priority' => 0, 'position' => 0, 'calculate_subtotal' => 0, 'customer_tax_class_ids' => array_values(array_unique($fixtureRule->getCustomerTaxClasses())), 'product_tax_class_ids' => array_values(array_unique($fixtureRule->getProductTaxClasses())), - 'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())) + 'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())), ], ]; $this->assertEquals($expectedRuleData, $searchResults['items']); diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php new file mode 100644 index 00000000000..372016ff301 --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria\CollectionProcessor; + + +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class JoinProcessor implements CollectionProcessorInterface +{ + /** + * @var CustomJoinInterface[] + */ + private $joins; + + /** + * @var array + */ + private $fieldMapping; + + /** @var array */ + private $appliedFields = []; + + /** + * @param CustomJoinInterface[] $customFilters + * @param array $fieldMapping + */ + public function __construct( + array $customJoins = [], + array $fieldMapping = [] + ) { + $this->joins = $customJoins; + $this->fieldMapping = $fieldMapping; + } + + /** + * Apply Search Criteria Filters to collection only if we need this + * + * @param SearchCriteriaInterface $searchCriteria + * @param AbstractDb $collection + * @return void + */ + public function process(SearchCriteriaInterface $searchCriteria, AbstractDb $collection) + { + if ($searchCriteria->getFilterGroups()) { + //Process filters + foreach ($searchCriteria->getFilterGroups() as $group) { + foreach ($group->getFilters() as $filter) { + if (!isset($this->appliedFields[$filter->getField()])) { + $this->applyCustomJoin($filter->getField(), $collection); + $this->appliedFields[$filter->getField()] = true; + } + } + } + } + + if ($searchCriteria->getSortOrders()) { + // Process Sortings + foreach ($searchCriteria->getSortOrders() as $order) { + if (!isset($this->appliedFields[$order->getField()])) { + $this->applyCustomJoin($order->getField(), $collection); + $this->appliedFields[$order->getField()] = true; + } + } + } + } + + /** + * Apply join to collection + * + * @param string $field + * @param AbstractDb $collection + * @return void + */ + private function applyCustomJoin($field, AbstractDb $collection) + { + $field = $this->getFieldMapping($field); + $customJoin = $this->getCustomJoin($field); + + if ($customJoin) { + $customJoin->apply($collection); + } + } + + /** + * Return custom filters for field if exists + * + * @param string $field + * @return CustomJoinInterface|null + * @throws \InvalidArgumentException + */ + private function getCustomJoin($field) + { + $filter = null; + if (isset($this->joins[$field])) { + $filter = $this->joins[$field]; + if (!($this->joins[$field] instanceof CustomJoinInterface)) { + throw new \InvalidArgumentException( + sprintf( + 'Filter for %s must implement %s interface.', + $field, + CustomJoinInterface::class + ) + ); + } + } + return $filter; + } + + /** + * Return mapped field name + * + * @param string $field + * @return string + */ + private function getFieldMapping($field) + { + return isset($this->fieldMapping[$field]) ? $this->fieldMapping[$field] : $field; + } +} diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor/CustomJoinInterface.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor/CustomJoinInterface.php new file mode 100644 index 00000000000..97692c4805e --- /dev/null +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor/CustomJoinInterface.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor; + +use Magento\Framework\Data\Collection\AbstractDb; + +/** + * @api + */ +interface CustomJoinInterface +{ + /** + * Make custom joins to collection + * + * @param AbstractDb $collection + * @return bool + */ + public function apply(AbstractDb $collection); +} diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/JoinProcessorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/JoinProcessorTest.php new file mode 100644 index 00000000000..d704f92f70e --- /dev/null +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessor/JoinProcessorTest.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Api\Test\Unit\SearchCriteria\CollectionProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Data\Collection\AbstractDb; + +class JoinProcessorTest extends \PHPUnit_Framework_TestCase +{ + /** + * Return model + * + * @param CustomJoinInterface[] $customJoins + * @param array $fieldMapping + * @return JoinProcessor + */ + private function getModel(array $customJoins, array $fieldMapping) + { + return new JoinProcessor($customJoins, $fieldMapping); + } + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testProcess() + { + /** @var \PHPUnit_Framework_MockObject_MockObject $customJoinMock */ + $customJoinMock = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor\CustomJoinInterface::class + ); + + $customField = 'customJoinField'; + $joins = [$customField => $customJoinMock]; + $fieldMapping = [ + 'customJoinFieldAzaza' => 'customJoinField' + ]; + + $model = $this->getModel($joins, $fieldMapping); + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + /** @var FilterGroup |\PHPUnit_Framework_MockObject_MockObject $JoinGroupOneMock */ + $filterGroup = $this->getMockBuilder(FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + + /** @var Filter |\PHPUnit_Framework_MockObject_MockObject $JoinThreeMock */ + $filter1 = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filter1->expects($this->atLeastOnce()) + ->method('getField') + ->willReturn('customJoinFieldAzaza'); + $filter2 = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filter2->expects($this->atLeastOnce()) + ->method('getField') + ->willReturn('someOtherField'); + $filterGroup->expects($this->once()) + ->method('getFilters') + ->willReturn([$filter1, $filter2]); + + $searchCriteriaMock->expects($this->exactly(2)) + ->method('getFilterGroups') + ->willReturn([$filterGroup]); + + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $customJoinMock->expects($this->once()) + ->method('apply') + ->with($collectionMock) + ->willReturn(true); + + $model->process($searchCriteriaMock, $collectionMock); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testProcessWithException() + { + /** @var \PHPUnit_Framework_MockObject_MockObject $customJoinMock */ + $customJoinMock = $this->getMockBuilder(\stdClass::class) + ->getMock(); + + $customField = 'customJoinField'; + $joins = [$customField => $customJoinMock]; + + /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock */ + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMock(); + + $model = $this->getModel($joins, []); + /** @var SortOrder |\PHPUnit_Framework_MockObject_MockObject $JoinGroupOneMock */ + $sortOrder = $this->getMockBuilder(SortOrder::class) + ->disableOriginalConstructor() + ->getMock(); + $sortOrder->expects($this->atLeastOnce()) + ->method('getField') + ->willReturn('customJoinField'); + $searchCriteriaMock->expects($this->exactly(2)) + ->method('getSortOrders') + ->willReturn([$sortOrder]); + /** @var AbstractDb|\PHPUnit_Framework_MockObject_MockObject $searchCriteriarMock */ + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMock(); + + $model->process($searchCriteriaMock, $collectionMock); + } +} -- GitLab From 404abed74c0375109a32f8457ead48bbef25bc41 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 15:14:24 +0300 Subject: [PATCH 113/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- .../Test/Unit/Model/QuoteRepositoryTest.php | 20 ---------------- .../Model/Calculation/RateRepositoryTest.php | 23 ------------------- .../Catalog/_files/products_for_search.php | 2 +- 3 files changed, 1 insertion(+), 44 deletions(-) diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index 2679c8c1465..fb4d738c978 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -422,7 +422,6 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $searchResult = $this->getMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class, [], [], '', false); $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); $cartMock = $this->getMock(\Magento\Payment\Model\Cart::class, [], [], '', false); - $filterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); $pageSize = 10; $this->searchResultsDataFactory @@ -434,28 +433,9 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase ->expects($this->once()) ->method('setSearchCriteria'); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $searchCriteriaMock - ->expects($this->any()) - ->method('getFilterGroups') - ->will($this->returnValue([$filterGroupMock])); - - //addFilterGroupToCollection() checks - $filterGroupMock->expects($this->any())->method('getFilters')->will($this->returnValue([$filterMock])); - $filterMock->expects($this->once())->method('getField')->will($this->returnValue('store_id')); - $filterMock->expects($this->any())->method('getConditionType')->will($this->returnValue('eq')); - $filterMock->expects($this->once())->method('getValue')->will($this->returnValue('filter_value')); - //back in getList() $this->quoteCollectionMock->expects($this->once())->method('getSize')->willReturn($pageSize); $searchResult->expects($this->once())->method('setTotalCount')->with($pageSize); - $sortOrderMock = $this->getMockBuilder(\Magento\Framework\Api\SortOrder::class) - ->setMethods(['getField', 'getDirection']) - ->disableOriginalConstructor() - ->getMock(); - - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->will($this->returnValue(1)); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->will($this->returnValue(10)); $this->quoteCollectionMock->expects($this->once())->method('setCurPage')->with(1); $this->quoteCollectionMock->expects($this->once())->method('setPageSize')->with(10); $this->collectionProcessor->expects($this->once()) diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php index b60ce0a7fbc..9289a80de71 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php @@ -377,17 +377,6 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetListWhenFilterGroupExists() { $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $searchCriteriaMock - ->expects($this->any()) - ->method('getFilterGroups') - ->will($this->returnValue([$filterGroupMock])); - $filterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $filterGroupMock->expects($this->once())->method('getFilters')->willReturn([$filterMock]); - $filterMock->expects($this->exactly(2))->method('getConditionType')->willReturn('like'); - $filterMock->expects($this->once())->method('getField')->willReturn('region_name'); - $filterMock->expects($this->once())->method('getValue')->willReturn('condition_value'); $objectManager = new ObjectManager($this); $rateMock = $this->getTaxRateMock([]); $items = [$rateMock]; @@ -395,18 +384,6 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase \Magento\Tax\Model\ResourceModel\Calculation\Rate\Collection::class, $items ); - $sortOrderMock = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); - $searchCriteriaMock - ->expects($this->any()) - ->method('getSortOrders') - ->will($this->returnValue([$sortOrderMock])); - $sortOrderMock->expects($this->once())->method('getField')->willReturn('field_name'); - $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC); - $collectionMock->expects($this->once())->method('addOrder')->with('main_table.field_name', 'ASC'); - $currentPage = 1; - $pageSize = 100; - $searchCriteriaMock->expects($this->any())->method('getCurrentPage')->will($this->returnValue($currentPage)); - $searchCriteriaMock->expects($this->any())->method('getPageSize')->will($this->returnValue($pageSize)); $rateMock = $this->getTaxRateMock([]); $this->collectionProcessor->expects($this->once()) ->method('process') diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php index 7d676327da6..0a06be7f9dd 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_for_search.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -include_once 'category.php'; +include 'category.php'; use Magento\Catalog\Api\CategoryLinkManagementInterface; use Magento\Catalog\Model\Product; -- GitLab From de76162fd00ed19580faa265a9b67e6211e2e921 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 16:04:02 +0300 Subject: [PATCH 114/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- .../Quote/Test/Unit/Model/QuoteRepositoryTest.php | 9 +++------ .../Magento/Tax/Model/Calculation/RateRepository.php | 1 - app/code/Magento/Tax/Model/TaxClass/Repository.php | 1 - .../Test/Unit/Model/Calculation/RateRepositoryTest.php | 3 +-- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index fb4d738c978..ce34306b4be 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -62,8 +62,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase private $loadHandlerMock; /** - * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface | - * \PHPUnit_Framework_MockObject_MockObject + * @var \PHPUnit_Framework_MockObject_MockObject */ private $collectionProcessor; @@ -418,7 +417,6 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetListSuccess() { - $this->markTestSkipped('MAGETWO-48531'); $searchResult = $this->getMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class, [], [], '', false); $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); $cartMock = $this->getMock(\Magento\Payment\Model\Cart::class, [], [], '', false); @@ -436,8 +434,6 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase //back in getList() $this->quoteCollectionMock->expects($this->once())->method('getSize')->willReturn($pageSize); $searchResult->expects($this->once())->method('setTotalCount')->with($pageSize); - $this->quoteCollectionMock->expects($this->once())->method('setCurPage')->with(1); - $this->quoteCollectionMock->expects($this->once())->method('setPageSize')->with(10); $this->collectionProcessor->expects($this->once()) ->method('process') ->with($searchCriteriaMock, $this->quoteCollectionMock); @@ -458,7 +454,8 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase 'storeManager' => $this->storeManagerMock, 'quoteCollection' => $this->quoteCollectionMock, 'searchResultsDataFactory' => $this->searchResultsDataFactory, - 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock + 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, + 'collectionProcessor' => $this->collectionProcessor, ] ); $this->model->expects($this->once())->method('getQuoteCollection')->willReturn($this->quoteCollectionMock); diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index e7531547e2a..07ab608acac 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -11,7 +11,6 @@ use Magento\Directory\Model\CountryFactory; use Magento\Directory\Model\RegionFactory; use Magento\Framework\Api\Search\FilterGroup; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; -use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; use Magento\Tax\Model\Calculation\Rate; diff --git a/app/code/Magento/Tax/Model/TaxClass/Repository.php b/app/code/Magento/Tax/Model/TaxClass/Repository.php index 880cc74dc3c..3ee54ae8aaa 100644 --- a/app/code/Magento/Tax/Model/TaxClass/Repository.php +++ b/app/code/Magento/Tax/Model/TaxClass/Repository.php @@ -11,7 +11,6 @@ use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\FilterGroup; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\CouldNotDeleteException; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException as ModelException; diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php index 9289a80de71..4a5a60a52e5 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php @@ -70,8 +70,7 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase private $joinProcessorMock; /** - * @var \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface - * | \PHPUnit_Framework_MockObject_MockObject + * @var \PHPUnit_Framework_MockObject_MockObject */ private $collectionProcessor; -- GitLab From 667fdda89f9d166f735ac4be7ce0e737925d5e75 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 16:11:53 +0300 Subject: [PATCH 115/838] MAGETWO-56008: Moving getStoreByWebsite to Store Module --- .../Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php b/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php index a325ade4ccd..7b8302578c2 100644 --- a/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php +++ b/app/code/Magento/Store/Model/ResourceModel/StoreWebsiteRelation.php @@ -19,7 +19,8 @@ class StoreWebsiteRelation * StoreWebsiteRelation constructor. * @param ResourceConnection $resource */ - public function __construct(ResourceConnection $resource) { + public function __construct(ResourceConnection $resource) + { $this->resource = $resource; } -- GitLab From b162ef0ca46bc5a3365f2aa0c215fa939b969fef Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 16:18:43 +0300 Subject: [PATCH 116/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Tax/Model/Calculation/RateRepository.php | 2 +- app/code/Magento/Tax/Model/TaxRuleRepository.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index 07ab608acac..3d331ec51a2 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -309,7 +309,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + '\Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessorComposite' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php index 51800ae71c4..b6fbaafb18e 100644 --- a/app/code/Magento/Tax/Model/TaxRuleRepository.php +++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php @@ -228,7 +228,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + '\Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite' ); } return $this->collectionProcessor; -- GitLab From 14c2ba6821b658cd3aecd200c8881ce8529307b2 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 09:01:22 -0500 Subject: [PATCH 117/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../Magento/Customer/Block/Widget/NameTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/NameTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/NameTest.php index 21249a2f642..71cc3c49460 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/NameTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/NameTest.php @@ -43,11 +43,11 @@ class NameTest extends \PHPUnit_Framework_TestCase $html = $this->_block->toHtml(); - $this->assertContains('title="First Name"', $html); + $this->assertContains('title="First Name"', $html); $this->assertContains('value="Jane"', $html); - $this->assertContains('title="Last Name"', $html); + $this->assertContains('title="Last Name"', $html); $this->assertContains('value="Doe"', $html); - $this->assertNotContains('title="Middle Name/Initial"', $html); + $this->assertNotContains('title="Middle Name/Initial"', $html); $this->assertNotContains('title="Prefix"', $html); $this->assertNotContains('title="Suffix"', $html); } @@ -78,11 +78,11 @@ class NameTest extends \PHPUnit_Framework_TestCase $html = $this->_block->toHtml(); - $this->assertContains('title="First Name"', $html); + $this->assertContains('title="First Name"', $html); $this->assertContains('value="Jane"', $html); - $this->assertContains('title="Last Name"', $html); + $this->assertContains('title="Last Name"', $html); $this->assertContains('value="Doe"', $html); - $this->assertContains('title="Middle Name/Initial"', $html); + $this->assertContains('title="Middle Name/Initial"', $html); $this->assertContains('value="Roe"', $html); $this->assertContains('title="Prefix"', $html); $this->assertContains('value="Dr."', $html); -- GitLab From 27eb1b2eef85b3c2c66437d5861048360a2ae8e1 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 3 Aug 2016 09:42:01 -0500 Subject: [PATCH 118/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../Captcha/view/adminhtml/templates/default.phtml | 4 ++-- .../Captcha/view/frontend/templates/default.phtml | 14 +++++++------- .../view/frontend/templates/remember_me.phtml | 4 ++-- .../SendFriend/view/frontend/templates/send.phtml | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index b4f1d095f45..1aceb9ff95d 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -36,8 +36,8 @@ alt="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"/> <img id="<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" - width="<?php /* @noEscape */ echo (int) $block->getImgWidth() ?>" - height="<?php /* @noEscape */ echo (int) $block->getImgHeight() ?>" + width="<?php /* @noEscape */ echo (float) $block->getImgWidth() ?>" + height="<?php /* @noEscape */ echo (float) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>" /> </div> <script> diff --git a/app/code/Magento/Captcha/view/frontend/templates/default.phtml b/app/code/Magento/Captcha/view/frontend/templates/default.phtml index 0739623dfa3..4046b5f96ec 100644 --- a/app/code/Magento/Captcha/view/frontend/templates/default.phtml +++ b/app/code/Magento/Captcha/view/frontend/templates/default.phtml @@ -10,19 +10,19 @@ <?php /* @var $captcha \Magento\Captcha\Model\DefaultModel */ ?> <?php /* @var $block \Magento\Captcha\Block\Captcha\DefaultCaptcha */ ?> <?php $captcha = $block->getCaptchaModel() ?> -<div class="field captcha required" role="<?php echo $block->escapeHtml($block->getFormId())?>"> - <label for="captcha_<?php echo $block->escapeHtml($block->getFormId()) ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Please type the letters below')?></span></label> +<div class="field captcha required" role="<?php echo $block->escapeHtmlAttr($block->getFormId())?>"> + <label for="captcha_<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Please type the letters below')?></span></label> <div class="control captcha"> - <input name="<?php echo $block->escapeHtml(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtml($block->getFormId())?>]" type="text" class="input-text required-entry" data-validate="{required:true}" id="captcha_<?php echo $block->escapeHtml($block->getFormId()) ?>" /> + <input name="<?php echo $block->escapeHtmlAttr(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtmlAttr($block->getFormId())?>]" type="text" class="input-text required-entry" data-validate="{required:true}" id="captcha_<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" /> <div class="nested"> <div class="field captcha no-label" - data-captcha="<?php echo $block->escapeHtml($block->getFormId())?>" - id="captcha-container-<?php echo $block->escapeHtml($block->getFormId())?>" + data-captcha="<?php echo $block->escapeHtmlAttr($block->getFormId())?>" + id="captcha-container-<?php echo $block->escapeHtmlAttr($block->getFormId())?>" data-mage-init='{"captcha":{"url": "<?php echo $block->escapeUrl($block->getRefreshUrl())?>", "imageLoader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-2.gif')) ?>", - "type": "<?php echo $block->escapeHtml($block->getFormId()) ?>"}}'> + "type": "<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>"}}'> <div class="control captcha-image"> - <img alt="<?php /* @escapeNotVerified */ echo __('Please type the letters below')?>" class="captcha-img" height="<?php echo (int) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>"/> + <img alt="<?php /* @escapeNotVerified */ echo __('Please type the letters below')?>" class="captcha-img" height="<?php /* @noEscape */ echo (float) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>"/> <button type="button" class="action reload captcha-reload" title="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"><span><?php /* @escapeNotVerified */ echo __('Reload captcha') ?></span></button> </div> </div> diff --git a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml index c7730933508..40cbb7dc64b 100644 --- a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml +++ b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml @@ -17,8 +17,8 @@ ?> <div id="remember-me-box" class="field choice persistent"> <?php $rememberMeId = 'remember_me' . $block->getRandomString(10); ?> - <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $block->escapeHtml($rememberMeId); ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> - <label for="<?php echo $block->escapeHtml($rememberMeId); ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> + <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> + <label for="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> <span class="tooltip wrapper"> <a class="link tooltip toggle" href="#"><?php /* @escapeNotVerified */ echo __('What\'s this?') ?></a> <span class="tooltip content"> diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 5d5b9d11241..edae5a01a31 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -49,7 +49,7 @@ "rowParentElem":"<div></div>", "remEventSelector":"button", "btnRemoveSelector":".action.remove", - "maxRows":"<?php echo (int)$block->getMaxRecipients() ?>", + "maxRows":"<?php /* @noEscape */ echo (int)$block->getMaxRecipients() ?>", "maxRowsMsg":"#max-recipient-message", "addRowBtn":"#add-recipient-button", "additionalRowClass":"additional"}, @@ -62,7 +62,7 @@ <div class="field sender required"> <label for="sender-name" class="label"><span><?php /* @escapeNotVerified */ echo __('Name') ?></span></label> <div class="control"> - <input name="sender[name]" value="<?php echo $block->escapeHtml($block->getUserName()) ?>" + <input name="sender[name]" value="<?php echo $block->escapeHtmlAttr($block->getUserName()) ?>" title="<?php /* @escapeNotVerified */ echo __('Name') ?>" id="sender-name" type="text" class="input-text" data-validate="{required:true}"/> </div> @@ -71,7 +71,7 @@ <div class="field email required"> <label for="sender-email" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> <div class="control"> - <input name="sender[email]" value="<?php echo $block->escapeHtml($block->getEmail()) ?>" + <input name="sender[email]" value="<?php echo $block->escapeHtmlAttr($block->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" id="sender-email" type="text" class="input-text" data-validate="{required:true, 'validate-email':true}"/> </div> -- GitLab From f68fe40910e16f349799761b17fa02ad0d04e538 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Wed, 3 Aug 2016 18:01:50 +0300 Subject: [PATCH 119/838] MAGETWO-55364: [WCAG 2.0 AA] Add Aria-Labels for Color Swatches - Set focus on first swatch block - Announce invalid options --- .../view/frontend/web/js/swatch-renderer.js | 42 ++++++++++++++- lib/web/mage/smart-keyboard-handler.js | 30 ++++++++--- lib/web/mage/validation.js | 52 ++++++++++--------- 3 files changed, 90 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 93c84c5a301..318b2b7066b 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -6,11 +6,47 @@ define([ 'jquery', 'underscore', + 'mage/smart-keyboard-handler', 'jquery/ui', - 'jquery/jquery.parsequery' -], function ($, _) { + 'jquery/jquery.parsequery', + 'mage/validation/validation' +], function ($, _, keyboardHandler) { 'use strict'; + $.widget('mage.validation', $.mage.validation, { + listenFormValidateHandler: function (event, validation) { + this._superApply(arguments); + + var swatchWrapper = $.mage.SwatchRenderer().options.classes.attributeOptionsWrapper, + firstActive = $(validation.errorList[0].element || []), + swatches = $(this).find('.' + swatchWrapper); + + if(swatches.length){ + var successList = validation.successList, + errorList = validation.errorList, + firstSwatch = $(firstActive).parent().find('.' + swatchWrapper); + + keyboardHandler.focus(swatches); + + if (successList.length) { + $.each(successList, function () { + $(this).parent().find('.' + swatchWrapper).attr('aria-invalid', false); + }) + } + + if (errorList.length) { + $.each(errorList, function (index, item) { + $(item.element).parent().find('.' + swatchWrapper).attr('aria-invalid', true); + }) + } + + if(firstSwatch.length){ + $(firstSwatch) .focus(); + } + } + } + }); + /** * Render tooltips by attributes (only to up). * Required element attributes: @@ -310,6 +346,8 @@ define([ label + '<div aria-activedescendant="" ' + 'tabindex="0" ' + + 'aria-invalid="false" ' + + 'aria-required="true" ' + 'role="listbox" ' + listLabel + 'class="' + classes.attributeOptionsWrapper + ' clearfix">' + options + select + diff --git a/lib/web/mage/smart-keyboard-handler.js b/lib/web/mage/smart-keyboard-handler.js index 859ab69372e..9a7e00afe7d 100644 --- a/lib/web/mage/smart-keyboard-handler.js +++ b/lib/web/mage/smart-keyboard-handler.js @@ -16,7 +16,8 @@ define([ CODE_TAB = 9; return { - apply: smartKeyboardFocus + apply: smartKeyboardFocus, + focus: handleFocus }; /** @@ -51,20 +52,35 @@ define([ */ function onFocusInHandler () { focusState = true; - $('body').addClass(tabFocusClass) + body.addClass(tabFocusClass) .off('focusin.keyboardHandler', onFocusInHandler); } /** * Handle logic to remove state after onTabKeyPress to normal. - * @param {Event} event */ - function onClickHandler(event) { - focusState = false; - $('body').removeClass(tabFocusClass) + function onClickHandler() { + focusState = false; + body.removeClass(tabFocusClass) .off('click', onClickHandler); } + + /** + * Attach smart focus on specific element. + * @param {HTMLElement} element + */ + function handleFocus(element) { + element.on('focusin', function () { + focusState = true; + body.addClass(tabFocusClass); + }); + + element.on('focusout', function () { + focusState = false; + body.removeClass(tabFocusClass); + }); + } } return new KeyboardHandler; -}); \ No newline at end of file +}); diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 60e180347ae..d3afca0ea8a 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1536,31 +1536,33 @@ * @protected */ _listenFormValidate: function () { - $('form').on('invalid-form.validate', function (event, validation) { - var firstActive = $(validation.errorList[0].element || []), - lastActive = $(validation.findLastActive() || validation.errorList.length && validation.errorList[0].element || []); - - if (lastActive.is(':hidden')) { - var parent = lastActive.parent(); - var windowHeight = $(window).height(); - $('html, body').animate({ - scrollTop: parent.offset().top - windowHeight / 2 - }); - } - - // ARIA (removing aria attributes if success) - var successList = validation.successList; - if (successList.length) { - $.each(successList, function () { - $(this) - .removeAttr('aria-describedby') - .removeAttr('aria-invalid'); - }) - } - if (firstActive.length) { - firstActive.focus(); - } - }); + $('form').on('invalid-form.validate', this.listenFormValidateHandler); + }, + + listenFormValidateHandler: function (event, validation) { + var firstActive = $(validation.errorList[0].element || []), + lastActive = $(validation.findLastActive() || validation.errorList.length && validation.errorList[0].element || []); + + if (lastActive.is(':hidden')) { + var parent = lastActive.parent(); + var windowHeight = $(window).height(); + $('html, body').animate({ + scrollTop: parent.offset().top - windowHeight / 2 + }); + } + + // ARIA (removing aria attributes if success) + var successList = validation.successList; + if (successList.length) { + $.each(successList, function () { + $(this) + .removeAttr('aria-describedby') + .removeAttr('aria-invalid'); + }) + } + if (firstActive.length) { + firstActive.focus(); + } } }); -- GitLab From bc5620c25215a39e64e120da8d2f9c765c11d50d Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 10:02:00 -0500 Subject: [PATCH 120/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../order/create/address/form/renderer/vat.phtml | 4 ++-- .../templates/system/config/validatevat.phtml | 7 ++----- .../view/adminhtml/templates/tab/cart.phtml | 3 ++- .../templates/tab/view/personal_info.phtml | 4 +--- .../view/adminhtml/templates/tab/view/sales.phtml | 3 ++- .../templates/account/authentication-popup.phtml | 2 ++ .../templates/account/dashboard/address.phtml | 3 ++- .../templates/account/dashboard/info.phtml | 3 ++- .../templates/account/link/authorization.phtml | 1 + .../view/frontend/templates/address/book.phtml | 8 ++------ .../view/frontend/templates/address/edit.phtml | 9 ++------- .../frontend/templates/form/confirmation.phtml | 2 ++ .../view/frontend/templates/form/edit.phtml | 3 ++- .../frontend/templates/form/forgotpassword.phtml | 2 ++ .../view/frontend/templates/form/login.phtml | 11 ++--------- .../view/frontend/templates/form/newsletter.phtml | 2 ++ .../view/frontend/templates/form/register.phtml | 9 ++------- .../templates/form/resetforgottenpassword.phtml | 1 + .../frontend/templates/js/customer-data.phtml | 6 +++--- .../frontend/templates/js/section-config.phtml | 6 +++--- .../Customer/view/frontend/templates/logout.phtml | 5 ++++- .../view/frontend/templates/newcustomer.phtml | 9 ++------- .../view/frontend/templates/widget/dob.phtml | 15 ++++----------- .../view/frontend/templates/widget/gender.phtml | 2 ++ .../view/frontend/templates/widget/name.phtml | 9 +++------ .../view/frontend/templates/widget/taxvat.phtml | 2 ++ 26 files changed, 56 insertions(+), 75 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml index 845227fdb2d..98b0556ec8e 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml @@ -6,8 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php +/** @var $block \Magento\Customer\Block\Adminhtml\Sales\Order\Address\Form\Renderer\Vat */ + $_element = $block->getElement(); $_note = $_element->getNote(); $_class = $_element->getFieldsetHtmlClass(); diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index 6caedc48e56..a08e4597b27 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -6,11 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * @see \Magento\Customer\Block\Adminhtml\System\Config\Validatevat - */ +/** @var $block \Magento\Customer\Block\Adminhtml\System\Config\Validatevat */ + ?> <script> require(['prototype'], function(){ diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index 3cbc496cfca..522712edf85 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -6,8 +6,9 @@ // @codingStandardsIgnoreFile +/* @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\Cart */ + ?> -<?php /* @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\Cart */ ?> <?php if ($block->getCartHeader()): ?> <div class="content-header skip-header"> <table> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml index c3b723c59d1..7c67215b5fa 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml @@ -6,9 +6,7 @@ // @codingStandardsIgnoreFile -/** - * @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo - */ +/** @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo */ $lastLoginDateAdmin = $block->getLastLoginDate(); $lastLoginDateStore = $block->getStoreLastLoginDate(); diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml index 08f999ca1a2..5aa176fdbd8 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml @@ -6,8 +6,9 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\Sales */ + ?> -<?php /** @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\Sales */ ?> <?php $singleStoreMode = $block->isSingleStoreMode(); ?> <div class="entry-edit fieldset-wrapper"> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index 2636887b23f..4f7455213cf 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -5,7 +5,9 @@ */ // @codingStandardsIgnoreFile + /** @var $block \Magento\Customer\Block\Account\AuthenticationPopup */ + ?> <div id="authenticationPopup" data-bind="scope:'authenticationPopup'" style="display: none;"> <script> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml index ed6f2a835cf..639c469ebe4 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml @@ -6,7 +6,8 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Customer\Block\Account\Dashboard\Address $block */ +/** @var $block \Magento\Customer\Block\Account\Dashboard\Address */ + ?> <div class="block block-dashboard-addresses"> <div class="block-title"> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml index 7eb24b1ffe8..e67b23bb02b 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml @@ -6,7 +6,8 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Customer\Block\Account\Dashboard\Info $block */ +/** @var $block \Magento\Customer\Block\Account\Dashboard\Info */ + ?> <div class="block block-dashboard-info"> <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Account Information') ?></strong></div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml index 53fafbc3109..673e5882785 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /** @var $block \Magento\Customer\Block\Account\AuthorizationLink */ + $dataPostParam = ''; if ($block->isLoggedIn()) { $dataPostParam = sprintf(" data-post='%s'", $block->getPostParams()); diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index a0a003904fc..8dc0ec180f4 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -6,12 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * Temlate for \Magento\Customer\Block\Address\Book block - * @var $block \Magento\Customer\Block\Address\Book - */ +/** @var $block \Magento\Customer\Block\Address\Book */ + ?> <div class="block block-addresses-default"> <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Default Addresses') ?></strong></div> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index 8ba5e82275a..930183de2a8 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -6,13 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * Edit customer address template - * - * @var $block \Magento\Customer\Block\Address\Edit - */ +/** @var $block \Magento\Customer\Block\Address\Edit */ + ?> <form class="form-address-edit" action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" diff --git a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml index 58ce17d7137..33debf7276d 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Framework\View\Element\Template */ + ?> <form action="" method="post" id="form-validate" class="form send confirmation" data-mage-init='{"validation":{}}'> <fieldset class="fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 89219df0e78..7ec19afe026 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -6,7 +6,8 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Customer\Block\Form\Edit $block */ +/** @var $block \Magento\Customer\Block\Form\Edit */ + ?> <form class="form form-edit-account" action="<?php echo $block->escapeUrl($block->getUrl('customer/account/editPost')) ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" autocomplete="off"> <fieldset class="fieldset info"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml index 9361fb5871f..2c4eaa47e07 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml @@ -8,6 +8,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Customer\Block\Account\Forgotpassword */ + ?> <form class="form password forget" action="<?php echo $block->escapeUrl($block->getUrl('*/*/forgotpasswordpost')) ?>" diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index 8f0713840e4..7ca93787618 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -6,15 +6,8 @@ // @codingStandardsIgnoreFile -/** @var \Magento\Customer\Block\Form\Login $block */ -?> -<?php -/** - * Customer login form template - * - * @see \Magento\Customer\Block\Form\Login - * @var $block \Magento\Customer\Block\Form\Login - */ +/** @var $block \Magento\Customer\Block\Form\Login */ + ?> <div class="block block-customer-login"> <div class="block-title"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml index c432da2ac04..1a7f4a3eefb 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Customer\Block\Newsletter */ + ?> <?php echo $block->getChildHtml('form_before')?> <form class="form form-newsletter-manage" action="<?php echo $block->escapeUrl($block->getAction()) ?>" method="post" id="form-validate"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index 38ea3068076..be6448574f6 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -6,13 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * Create account form template - * - * @var $block \Magento\Customer\Block\Form\Register - */ +/** @var $block \Magento\Customer\Block\Form\Register */ + ?> <?php echo $block->getChildHtml('form_fields_before')?> <?php /* Extensions placeholder */ ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml index 6b3b34fc00e..868409a5fad 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml @@ -7,6 +7,7 @@ // @codingStandardsIgnoreFile /** @var \Magento\Customer\Block\Account\Resetpassword $block */ + ?> <form action="<?php echo $block->escapeUrl($block->getUrl('*/*/resetpasswordpost', ['_query' => ['id' => $block->getCustomerId(), 'token' => $block->getResetPasswordLinkToken()]])); ?>" method="post" diff --git a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml index 3a2bd0dd74a..13667dabc3c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml @@ -3,9 +3,9 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -/** - * @var \Magento\Customer\Block\CustomerData $block - */ + +/** @var $block \Magento\Customer\Block\CustomerData */ + ?> <script type="text/x-magento-init"> <?php diff --git a/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml b/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml index d48fbff4e80..8e869d08c87 100644 --- a/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml @@ -3,9 +3,9 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -/** - * @var \Magento\Customer\Block\SectionConfig $block - */ + +/** @var $block \Magento\Customer\Block\SectionConfig */ + ?> <script type="text/x-magento-init"> <?php diff --git a/app/code/Magento/Customer/view/frontend/templates/logout.phtml b/app/code/Magento/Customer/view/frontend/templates/logout.phtml index 089444ff078..c79d9a28b10 100644 --- a/app/code/Magento/Customer/view/frontend/templates/logout.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/logout.phtml @@ -3,6 +3,9 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** @var $block \Magento\Framework\View\Element\Template */ + ?> <p><?php /* @escapeNotVerified */ echo __('You have signed out and will go to our homepage in 5 seconds.') ?></p> <script> @@ -11,7 +14,7 @@ require([ "mage/mage" ], function($){ - $($.mage.redirect("<?php echo $block->escapeJs($block->getUrl()) ?>", "assign", 5000)); + $($.mage.redirect("<?php echo $block->escapeUrl($block->getUrl()) ?>", "assign", 5000)); }); </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml index 39d41e6b782..def74853681 100644 --- a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml @@ -6,13 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * New Customer block template - * - * @var $block \Magento\Customer\Block\Form\Login\Info - */ +/** @var $block \Magento\Customer\Block\Form\Login\Info */ + ?> <?php if ($block->getRegistration()->isAllowed()): ?> <div class="block block-new-customer"> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml index 3eaa230b684..3e2e372196d 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml @@ -6,11 +6,9 @@ // @codingStandardsIgnoreFile -/** -USAGE: - -Simple: +/** @var $block \Magento\Customer\Block\Widget\Dob */ +/* <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Dob') ->setDate($block->getCustomer()->getDob()) ->toHtml() ?> @@ -23,15 +21,10 @@ For checkout/onepage/billing.phtml: ->setFieldNameFormat('billing[%s]') ->toHtml() ?> -NOTE: Regarding styles - if we leave it this way, we'll move it to boxes.css - Alternatively we could calculate widths automatically using block input parameters. +NOTE: Regarding styles - if we leave it this way, we'll move it to boxes.css. Alternatively we could calculate widths +automatically using block input parameters. */ -/** - * @see \Magento\Customer\Block\Widget\Dob - */ -?> -<?php $fieldCssClass = 'field date field-' . $block->getHtmlId(); $fieldCssClass .= $block->isRequired() ? ' required' : ''; ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml index 3c766812be3..cfe8c874beb 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Customer\Block\Widget\Gender */ + ?> <div class="field gender<?php if ($block->isRequired()) echo ' required' ?>"> <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index d8758f0bc76..d5e61ee3af7 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -6,11 +6,9 @@ // @codingStandardsIgnoreFile -/** -USAGE: - -Simple: +/** @var $block \Magento\Customer\Block\Widget\Name */ +/* <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name') ->setObject($block->getAddress()) ->toHtml() ?> @@ -24,12 +22,11 @@ For checkout/onepage/shipping.phtml: ->setFieldParams('onchange="shipping.setSameAsBilling(false);"') ->toHtml() ?> */ -/* @var $block \Magento\Customer\Block\Widget\Name */ + $prefix = $block->showPrefix(); $middle = $block->showMiddlename(); $suffix = $block->showSuffix(); ?> - <?php if (($prefix || $middle || $suffix) && !$block->getNoWrap()): ?> <div class="field required fullname <?php echo $block->escapeHtmlAttr($block->getContainerClassName()) ?>"> <label for="<?php echo $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>" class="label"> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml index b903ef47f20..54c4bf588ec 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Customer\Block\Widget\Taxvat */ + ?> <div class="field taxvat<?php if ($block->isRequired()) echo ' required'; ?>"> <label class="label" for="<?php echo $block->escapeHtml($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> -- GitLab From 06b240d374fd9eaff31012017a5f03ffd5ef3a7f Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 18:04:01 +0300 Subject: [PATCH 121/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Tax/Model/Calculation/RateRepository.php | 1 + app/code/Magento/Tax/Model/TaxRuleRepository.php | 3 +-- app/code/Magento/Tax/etc/di.xml | 5 ++++- .../Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index 3d331ec51a2..3ccf822e865 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -201,6 +201,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface /** * Translates a field name to a DB column name for use in collection queries. * + * @deprecated * @param string $field a field name that should be translated to a DB column name. * @return string */ diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php index b6fbaafb18e..5fdb2483b3e 100644 --- a/app/code/Magento/Tax/Model/TaxRuleRepository.php +++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php @@ -147,10 +147,9 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface $searchResults->setSearchCriteria($searchCriteria); $collection = $this->collectionFactory->create(); $this->joinProcessor->process($collection); + $this->collectionProcessor->process($searchCriteria, $collection); $searchResults->setTotalCount($collection->getSize()); - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); $searchResults->setItems($collection->getItems()); return $searchResults; diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 01121b3ac2b..8ae648a6294 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -132,6 +132,7 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> @@ -142,6 +143,7 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> @@ -152,14 +154,15 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> <virtualType name="Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> <arguments> <argument name="processors" xsi:type="array"> - <item name="filters" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> <item name="joins" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\JoinProcessor</item> + <item name="filters" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> <item name="sorting" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> </argument> diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php index ee352a5fa80..7df25a2edba 100644 --- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php @@ -343,15 +343,15 @@ class TaxRuleRepositoryInterfaceTest extends WebapiAbstract $taxRate = $this->taxRate->load('*', 'code'); $filter2 = $this->filterBuilder - ->setField('cd.customer_tax_class_id') + ->setField('customer_tax_class_ids') ->setValue($customerTaxClass->getClassId()) ->create(); $filter3 = $this->filterBuilder - ->setField('ptc.product_tax_class_id') + ->setField('product_tax_class_ids') ->setValue($productTaxClass->getClassId()) ->create(); $filter4 = $this->filterBuilder - ->setField('rate.tax_calculation_rate_id') + ->setField('tax_calculation_rate_id') ->setValue($taxRate->getId()) ->create(); $sortOrder = $this->sortOrderBuilder -- GitLab From fc578191bf8e2465b518972f4b7c0c6b1b748531 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 3 Aug 2016 18:04:52 +0300 Subject: [PATCH 122/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- .../Api/SearchCriteria/CollectionProcessor/JoinProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php index 372016ff301..7cf9020f172 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor/JoinProcessor.php @@ -102,7 +102,7 @@ class JoinProcessor implements CollectionProcessorInterface if (!($this->joins[$field] instanceof CustomJoinInterface)) { throw new \InvalidArgumentException( sprintf( - 'Filter for %s must implement %s interface.', + 'Custom join for %s must implement %s interface.', $field, CustomJoinInterface::class ) -- GitLab From 8578fc4dc134e2b7968d17668dc929de23b6b0ff Mon Sep 17 00:00:00 2001 From: Rykh Oleksandr <orykh@magento.com> Date: Wed, 3 Aug 2016 18:26:25 +0300 Subject: [PATCH 123/838] MTA-3464: Merge Domain Functional Bamboo Plan --- .../app/Magento/Backend/Test/TestCase/ExpireAdminSessionTest.php | 1 - .../app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php | 1 - .../Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php | 1 - .../app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php | 1 - .../tests/app/Magento/Backend/Test/TestCase/NavigateMenuTest.php | 1 - .../Braintree/Test/TestCase/BraintreeSettlementReportTest.php | 1 - .../Test/TestCase/CheckoutWithBraintreePaypalCartTest.php | 1 - .../Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php | 1 - .../Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php | 1 - .../Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php | 1 - .../Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php | 1 - .../Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php | 1 - .../Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php | 1 - .../Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php | 1 - .../Bundle/Test/TestCase/CreateBundleProductEntityTest.php | 1 - .../Bundle/Test/TestCase/UpdateBundleProductEntityTest.php | 1 - .../Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php | 1 - .../Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php | 1 - .../Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php | 1 - .../Catalog/Test/TestCase/Product/AddCompareProductsTest.php | 1 - .../Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php | 1 - .../Test/TestCase/Product/ClearAllCompareProductsTest.php | 1 - .../Test/TestCase/Product/CreateSimpleProductEntityTest.php | 1 - .../Test/TestCase/Product/CreateVirtualProductEntityTest.php | 1 - .../Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php | 1 - .../Catalog/Test/TestCase/Product/DeleteProductEntityTest.php | 1 - .../Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php | 1 - .../Catalog/Test/TestCase/Product/MassProductUpdateTest.php | 1 - .../Test/TestCase/Product/NavigateRelatedProductsTest.php | 1 - .../Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php | 1 - .../Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php | 1 - .../Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php | 1 - .../Test/TestCase/Product/UpdateSimpleProductEntityTest.php | 1 - .../Test/TestCase/Product/UpdateVirtualProductEntityTest.php | 1 - .../Test/TestCase/Product/ValidateOrderOfProductTypeTest.php | 1 - .../TestCase/ProductAttribute/CreateAttributeSetEntityTest.php | 1 - .../CreateProductAttributeEntityFromProductPageTest.php | 1 - .../ProductAttribute/CreateProductAttributeEntityTest.php | 1 - .../DeleteAssignedToTemplateProductAttributeTest.php | 1 - .../Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php | 1 - .../ProductAttribute/DeleteProductAttributeEntityTest.php | 1 - .../ProductAttribute/DeleteSystemProductAttributeTest.php | 1 - .../DeleteUsedInConfigurableProductAttributeTest.php | 1 - .../Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php | 1 - .../ProductAttribute/UpdateProductAttributeEntityTest.php | 1 - .../CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php | 1 - .../Test/TestCase/CreateCatalogPriceRuleEntityTest.php | 1 - .../Test/TestCase/DeleteCatalogPriceRuleEntityTest.php | 1 - .../Test/TestCase/UpdateCatalogPriceRuleEntityTest.php | 1 - .../CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php | 1 - .../CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php | 1 - .../CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php | 1 - .../Test/TestCase/MassDeleteSearchTermEntityTest.php | 1 - .../CatalogSearch/Test/TestCase/SearchEntityResultsTest.php | 1 - .../Test/TestCase/SuggestSearchingResultEntityTest.php | 1 - .../CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php | 1 - .../Test/TestCase/AddProductsToShoppingCartEntityTest.php | 1 - .../Test/TestCase/DeleteProductFromMiniShoppingCartTest.php | 1 - .../Test/TestCase/DeleteProductsFromShoppingCartTest.php | 1 - .../app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php | 1 - .../TestCase/UpdateProductFromMiniShoppingCartEntityTest.php | 1 - .../Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php | 1 - .../CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php | 1 - .../CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php | 1 - .../CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php | 1 - .../app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php | 1 - .../app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php | 1 - .../Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php | 1 - .../app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php | 1 - .../app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php | 1 - .../Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php | 1 - .../app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php | 1 - .../app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php | 1 - .../Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php | 1 - .../Test/TestCase/CreateConfigurableProductEntityTest.php | 1 - .../Test/TestCase/UpdateConfigurableProductEntityTest.php | 1 - .../Test/TestCase/EditCurrencySymbolEntityTest.php | 1 - .../Test/TestCase/ResetCurrencySymbolEntityTest.php | 1 - .../tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php | 1 - .../Customer/Test/TestCase/ChangeCustomerPasswordTest.php | 1 - .../Customer/Test/TestCase/CreateCustomerBackendEntityTest.php | 1 - .../Customer/Test/TestCase/CreateCustomerGroupEntityTest.php | 1 - .../Test/TestCase/CreateExistingCustomerBackendEntity.php | 1 - .../Test/TestCase/CreateExistingCustomerFrontendEntity.php | 1 - .../Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php | 1 - .../Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php | 1 - .../Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php | 1 - .../Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php | 1 - .../Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php | 1 - .../Customer/Test/TestCase/MassAssignCustomerGroupTest.php | 1 - .../Test/TestCase/MassDeleteCustomerBackendEntityTest.php | 1 - .../Test/TestCase/RegisterCustomerFrontendEntityTest.php | 1 - .../Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php | 1 - .../Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php | 1 - .../Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php | 1 - .../Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php | 1 - .../Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php | 1 - .../Test/TestCase/CreateDownloadableProductEntityTest.php | 1 - .../Test/TestCase/UpdateDownloadableProductEntityTest.php | 1 - .../GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php | 1 - .../Test/TestCase/CreateGroupedProductEntityTest.php | 1 - .../Test/TestCase/UpdateGroupedProductEntityTest.php | 1 - .../Integration/Test/TestCase/ActivateIntegrationEntityTest.php | 1 - .../Integration/Test/TestCase/CreateIntegrationEntityTest.php | 1 - .../Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php | 1 - .../Integration/Test/TestCase/DeleteIntegrationEntityTest.php | 1 - .../Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php | 1 - .../Integration/Test/TestCase/UpdateIntegrationEntityTest.php | 1 - .../LayeredNavigation/Test/TestCase/FilterProductListTest.php | 1 - .../tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php | 1 - .../Test/TestCase/ActionNewsletterTemplateEntityTest.php | 1 - .../Test/TestCase/CreateNewsletterTemplateEntityTest.php | 1 - .../Test/TestCase/PreviewNewsletterTemplateEntityTest.php | 1 - .../Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php | 1 - .../PageCache/Test/TestCase/FlushAdditionalCachesTest.php | 1 - .../Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php | 1 - .../Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php | 1 - .../Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php | 1 - .../Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php | 1 - .../TestCase/InContextExpressCheckoutFromShoppingCartTest.php | 1 - .../Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php | 1 - .../Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php | 1 - .../ProductVideo/Test/TestCase/DeleteProductVideoTest.php | 1 - .../ProductVideo/Test/TestCase/UpdateProductVideoTest.php | 1 - .../Reports/Test/TestCase/AbandonedCartsReportEntityTest.php | 1 - .../Reports/Test/TestCase/BestsellerProductsReportEntityTest.php | 1 - .../Reports/Test/TestCase/CustomerReviewReportEntityTest.php | 1 - .../Test/TestCase/CustomersOrderCountReportEntityTest.php | 1 - .../Test/TestCase/CustomersOrderTotalReportEntityTest.php | 1 - .../Reports/Test/TestCase/DownloadProductsReportEntityTest.php | 1 - .../Reports/Test/TestCase/LowStockProductsReportEntityTest.php | 1 - .../Reports/Test/TestCase/NewAccountsReportEntityTest.php | 1 - .../Reports/Test/TestCase/OrderedProductsReportEntityTest.php | 1 - .../Reports/Test/TestCase/ProductReviewReportEntityTest.php | 1 - .../Reports/Test/TestCase/ProductsInCartReportEntityTest.php | 1 - .../Reports/Test/TestCase/SalesCouponReportEntityTest.php | 1 - .../Reports/Test/TestCase/SalesInvoiceReportEntityTest.php | 1 - .../Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php | 1 - .../Reports/Test/TestCase/SalesRefundsReportEntityTest.php | 1 - .../Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php | 1 - .../Reports/Test/TestCase/SearchTermsReportEntityTest.php | 1 - .../Reports/Test/TestCase/ViewedProductsReportEntityTest.php | 1 - .../Review/Test/TestCase/CreateProductRatingEntityTest.php | 1 - .../Test/TestCase/CreateProductReviewBackendEntityTest.php | 1 - .../Test/TestCase/CreateProductReviewFrontendEntityTest.php | 1 - .../Review/Test/TestCase/DeleteProductRatingEntityTest.php | 1 - .../Test/TestCase/ManageProductReviewFromCustomerPageTest.php | 1 - .../Review/Test/TestCase/MassActionsProductReviewEntityTest.php | 1 - .../Review/Test/TestCase/ModerateProductReviewEntityTest.php | 1 - .../Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php | 1 - .../Review/Test/TestCase/UpdateProductReviewEntityTest.php | 1 - .../Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php | 1 - .../app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php | 1 - .../Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php | 1 - .../Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php | 1 - .../app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php | 1 - .../Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php | 1 - .../app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php | 1 - .../app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php | 1 - .../app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php | 1 - .../Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php | 1 - .../Test/TestCase/MoveProductsInComparedOnOrderPageTest.php | 1 - .../TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php | 1 - .../Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php | 1 - .../Test/TestCase/MoveShoppingCartProductsOnOrderPageTest.php | 1 - .../Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php | 1 - .../app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php | 1 - .../Sales/Test/TestCase/UnassignCustomOrderStatusTest.php | 1 - .../Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php | 1 - .../SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php | 1 - .../SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php | 1 - .../SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php | 1 - .../SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php | 1 - .../SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php | 1 - .../Search/Test/TestCase/CreateSynonymGroupEntityTest.php | 1 - .../Search/Test/TestCase/DeleteSynonymGroupEntityTest.php | 1 - .../Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php | 1 - .../Search/Test/TestCase/UpdateSynonymGroupEntityTest.php | 1 - .../TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php | 1 - .../Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php | 1 - .../Security/Test/TestCase/LockCustomerOnEditPageTest.php | 1 - .../Security/Test/TestCase/LockCustomerOnLoginPageTest.php | 1 - .../Security/Test/TestCase/NewCustomerPasswordComplexityTest.php | 1 - .../Security/Test/TestCase/ResetCustomerPasswordFailedTest.php | 1 - .../Security/Test/TestCase/ResetUserPasswordFailedTest.php | 1 - .../Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php | 1 - .../Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php | 1 - .../Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php | 1 - .../app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php | 1 - .../Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php | 1 - .../app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php | 1 - .../app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php | 1 - .../Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php | 1 - .../app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php | 1 - .../app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php | 1 - .../Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php | 1 - .../app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php | 1 - .../Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php | 1 - .../app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php | 1 - .../app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php | 1 - .../app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php | 1 - .../app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php | 1 - .../app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php | 1 - .../tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php | 1 - .../app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php | 1 - .../app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php | 1 - .../app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php | 1 - .../tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php | 1 - .../app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php | 1 - .../tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php | 1 - .../UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php | 1 - .../Test/TestCase/CreateCustomUrlRewriteEntityTest.php | 1 - .../Test/TestCase/CreateProductUrlRewriteEntityTest.php | 1 - .../Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php | 1 - .../Test/TestCase/DeleteCustomUrlRewriteEntityTest.php | 1 - .../Test/TestCase/DeleteProductUrlRewriteEntityTest.php | 1 - .../Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php | 1 - .../Test/TestCase/UpdateCustomUrlRewriteEntityTest.php | 1 - .../Test/TestCase/UpdateProductUrlRewriteEntityTest.php | 1 - .../app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php | 1 - .../Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php | 1 - .../app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php | 1 - .../app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php | 1 - .../app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php | 1 - .../TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php | 1 - .../app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php | 1 - .../Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php | 1 - .../User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php | 1 - .../Variable/Test/TestCase/CreateCustomVariableEntityTest.php | 1 - .../Variable/Test/TestCase/DeleteCustomVariableEntityTest.php | 1 - .../Variable/Test/TestCase/UpdateCustomVariableEntityTest.php | 1 - .../Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php | 1 - .../Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php | 1 - .../app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php | 1 - .../app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php | 1 - .../app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php | 1 - .../app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php | 1 - .../app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php | 1 - .../Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php | 1 - .../AddProductsToCartFromCustomerWishlistOnFrontendTest.php | 1 - .../TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php | 1 - .../ConfigureProductInCustomerWishlistOnFrontendTest.php | 1 - .../TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php | 1 - .../Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php | 1 - .../Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php | 1 - .../Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php | 1 - .../Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php | 1 - 247 files changed, 247 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ExpireAdminSessionTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ExpireAdminSessionTest.php index 4511840ccdb..048f92783b4 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ExpireAdminSessionTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/ExpireAdminSessionTest.php @@ -30,7 +30,6 @@ class ExpireAdminSessionTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ protected $systemConfigEdit; diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php index f0dbb4fbc2a..4261e9fa82d 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php @@ -29,7 +29,6 @@ class GlobalSearchEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php index 95e69835435..0c2cd138eb1 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php @@ -25,7 +25,6 @@ class HttpsHeadersDisableTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php index 412329700ef..5dca7fad04e 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php @@ -25,7 +25,6 @@ class HttpsHeadersEnableTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/NavigateMenuTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/NavigateMenuTest.php index 4973598ac59..f75ea3ade05 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/NavigateMenuTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/NavigateMenuTest.php @@ -21,7 +21,6 @@ class NavigateMenuTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php index 95b2234607d..9b1bb894b0d 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php @@ -37,7 +37,6 @@ class BraintreeSettlementReportTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php index 8bad13557c8..26c1c6f0797 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php @@ -32,7 +32,6 @@ class CheckoutWithBraintreePaypalCartTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php index d6723c71816..e7b36898991 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php @@ -32,7 +32,6 @@ class CheckoutWithBraintreePaypalMinicartTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php index f45270012dd..0631acd511f 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php @@ -24,7 +24,6 @@ class CreateOnlineCreditMemoBraintreePaypalTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php index 625c24866e3..d2db16e5be4 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php @@ -28,7 +28,6 @@ class InvoicePayPalBraintreeTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php index 5b6e254cee0..090487489be 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php @@ -38,7 +38,6 @@ class OnePageCheckoutWith3dSecureTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php index 092a03b78ed..ee954b671be 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php @@ -36,7 +36,6 @@ class OnePageCheckoutWithBraintreePaypalTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php index 107918b973d..58496d34f97 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php @@ -42,7 +42,6 @@ class SaveUseDeleteVaultForPaypalBraintreeTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php index a0d850f07e9..5377506cff9 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php @@ -42,7 +42,6 @@ class UseVaultWith3dSecureOnCheckoutTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php index 8a24aed55cb..4a064d840c9 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php @@ -29,7 +29,6 @@ class CreateBundleProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php index ca7683fca93..1348507c2dd 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php @@ -33,7 +33,6 @@ class UpdateBundleProductEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php index e648c84cf9a..00fabef8456 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php @@ -29,7 +29,6 @@ class CreateCategoryEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php index 36bcf1a4386..db166505fab 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php @@ -32,7 +32,6 @@ class DeleteCategoryEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php index b37aba462dc..66b09b2f4b7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php @@ -34,7 +34,6 @@ class UpdateCategoryEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** 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 ec87faa5f11..1de71d149ee 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 @@ -29,7 +29,6 @@ class AddCompareProductsTest extends AbstractCompareProductsTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php index 50819db0f15..4a1ef07b454 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php @@ -27,7 +27,6 @@ class AddToCartCrossSellTest extends AbstractProductPromotedProductsTest /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php index 72a0b88ddf0..a3fec9105ac 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php @@ -28,7 +28,6 @@ class ClearAllCompareProductsTest extends AbstractCompareProductsTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php index 97b2a0715f7..76b013d5696 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php @@ -29,7 +29,6 @@ class CreateSimpleProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php index 86e45f9686c..6ee67d04cf9 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php @@ -31,7 +31,6 @@ class CreateVirtualProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php index 70c1757b82d..75a419df04c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php @@ -28,7 +28,6 @@ class DeleteCompareProductsTest extends AbstractCompareProductsTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php index bfc9e153a9e..617c3d45310 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php @@ -30,7 +30,6 @@ class DeleteProductEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php index dd0f5e221fa..d7d98b19df3 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php @@ -30,7 +30,6 @@ class DuplicateProductEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php index 36c04d0bbbd..7ab1ffaa6e0 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php @@ -35,7 +35,6 @@ class MassProductUpdateTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php index 53451339e07..a8792ba6c8e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php @@ -27,7 +27,6 @@ class NavigateRelatedProductsTest extends AbstractProductPromotedProductsTest /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php index 53e3a57a2e8..ee375563241 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php @@ -24,7 +24,6 @@ class NavigateUpSellProductsTest extends AbstractProductPromotedProductsTest /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php index 5a97e8922ce..0a29696e463 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php @@ -29,7 +29,6 @@ class ProductTypeSwitchingOnCreationTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php index 55814088db4..066045e4836 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php @@ -37,7 +37,6 @@ class ProductTypeSwitchingOnUpdateTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php index d2730644dc6..0a8b9f0bfb7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php @@ -33,7 +33,6 @@ class UpdateSimpleProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php index 43d44b577ab..64d3b68a988 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php @@ -37,7 +37,6 @@ class UpdateVirtualProductEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php index eff2ef2a697..148b1d2b8bf 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php @@ -21,7 +21,6 @@ class ValidateOrderOfProductTypeTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php index a20282f786a..c66fdfd5a49 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php @@ -32,7 +32,6 @@ class CreateAttributeSetEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php index e40006301ff..1f335e2a590 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php @@ -31,7 +31,6 @@ class CreateProductAttributeEntityFromProductPageTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php index 034acb5918b..49d3d3fddad 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php @@ -24,7 +24,6 @@ class CreateProductAttributeEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php index e8f20837bf3..bf43658890c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php @@ -31,7 +31,6 @@ class DeleteAssignedToTemplateProductAttributeTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php index b71e751015d..ac0d6566b94 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php @@ -34,7 +34,6 @@ class DeleteAttributeSetTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php index 0b0e078015a..3cf6395a08c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php @@ -30,7 +30,6 @@ class DeleteProductAttributeEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php index e57a00a9d68..456eadfa1fe 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php @@ -27,7 +27,6 @@ class DeleteSystemProductAttributeTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php index 40c05f9f75a..0ddaa387804 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php @@ -35,7 +35,6 @@ class DeleteUsedInConfigurableProductAttributeTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php index 37ebda4406c..51cb635bd6f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php @@ -36,7 +36,6 @@ class UpdateAttributeSetTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php index e30bb6622af..b669b940ac2 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php @@ -35,7 +35,6 @@ class UpdateProductAttributeEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php index 1da500b3864..3ce7dc159c0 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php @@ -31,7 +31,6 @@ class ApplyCatalogPriceRulesTest extends AbstractCatalogRuleEntityTest /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php index bbab44b01d5..c46cc72bf79 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php @@ -28,7 +28,6 @@ class CreateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php index 89dd079aecd..9bc68a959bf 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php @@ -31,7 +31,6 @@ class DeleteCatalogPriceRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php index 2f04d13ca44..b045460053d 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php @@ -32,7 +32,6 @@ class UpdateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php index 90234c28627..7014196fa0d 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php @@ -30,7 +30,6 @@ class AdvancedSearchEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php index a6853a8c475..f92d55a9b85 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php @@ -30,7 +30,6 @@ class CreateSearchTermEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php index d646ffc6c4a..f7d4114b748 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php @@ -33,7 +33,6 @@ class DeleteSearchTermEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php index c64d5f5d72a..85afc4013dc 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php @@ -34,7 +34,6 @@ class MassDeleteSearchTermEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php index 77aa6b169cb..7d0a6179ed1 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php @@ -26,7 +26,6 @@ class SearchEntityResultsTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php index 285fb7b3daf..376214dc004 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php @@ -28,7 +28,6 @@ class SuggestSearchingResultEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php index b58fc2083a4..f50293bbe5e 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php @@ -33,7 +33,6 @@ class UpdateSearchTermEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php index 8eed34db7e3..6de035b5ca3 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php @@ -30,7 +30,6 @@ class AddProductsToShoppingCartEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php index 4997ed168f3..2e2b286dc32 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php @@ -32,7 +32,6 @@ class DeleteProductFromMiniShoppingCartTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php index 40edbd64dd0..c53d3e0a2bd 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php @@ -30,7 +30,6 @@ class DeleteProductsFromShoppingCartTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php index 40789d462d1..6e00ad65420 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php @@ -40,7 +40,6 @@ class OnePageCheckoutTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test, 3rd_party_test'; /* end tags */ 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 709b131c956..806b72c23e2 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 @@ -32,7 +32,6 @@ class UpdateProductFromMiniShoppingCartEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php index 89563fe97ba..8b4fc487832 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php @@ -33,7 +33,6 @@ class UpdateShoppingCartTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php index 6cb7dac0853..d8cc5935c37 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php @@ -26,7 +26,6 @@ class CreateTermEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php index ab9c1484ef3..d88e01a6c8a 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php @@ -26,7 +26,6 @@ class DeleteTermEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php index 1a054cd8991..816208c578b 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php @@ -27,7 +27,6 @@ class UpdateTermEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php index 33824a8a84f..fcd78e0543d 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php @@ -26,7 +26,6 @@ class CreateCmsBlockEntityTest extends AbstractCmsBlockEntityTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php index ca6f7a8d3f6..398201e7376 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php @@ -28,7 +28,6 @@ class CreateCmsPageEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php index d4d15290d7b..fcd031f4037 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php @@ -32,7 +32,6 @@ class CreateCmsPageRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php index c4897ea3626..b0257e0cd5e 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php @@ -31,7 +31,6 @@ class DeleteCmsBlockEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php index 1a52df3142f..777345ca2cf 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php @@ -29,7 +29,6 @@ class DeleteCmsPageEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php index ac8f69b3fb5..b08bb14d4d0 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php @@ -30,7 +30,6 @@ class DeleteCmsPageUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php index f42078879c5..fb9ac37993a 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php @@ -27,7 +27,6 @@ class UpdateCmsBlockEntityTest extends AbstractCmsBlockEntityTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php index 280b2cd915a..b0b67a1e75c 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php @@ -31,7 +31,6 @@ class UpdateCmsPageEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php index edec851d866..8ebf371d73e 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php @@ -35,7 +35,6 @@ class UpdateCmsPageRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php index c800c8b1bfe..93a19cf6874 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php @@ -41,7 +41,6 @@ class CreateConfigurableProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php index e9014ca2476..f08484f605e 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php @@ -32,7 +32,6 @@ class UpdateConfigurableProductEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php index f98745d22e1..e53a403e8ca 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php @@ -27,7 +27,6 @@ class EditCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php index 25895dc27e7..1a6b9b8094f 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php @@ -28,7 +28,6 @@ class ResetCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php index bc0fea4b563..88d51e97350 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php @@ -32,7 +32,6 @@ class ApplyVatIdTest extends AbstractApplyVatIdTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php index ecc981db972..a01c6d34069 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php @@ -33,7 +33,6 @@ class ChangeCustomerPasswordTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php index 0ad79c4c493..bf3ae060a6d 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php @@ -27,7 +27,6 @@ class CreateCustomerBackendEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php index 25ff9ff25db..63e679b78b8 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php @@ -29,7 +29,6 @@ class CreateCustomerGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.php index 502e9d06092..1f13c6ccdac 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerBackendEntity.php @@ -29,7 +29,6 @@ class CreateExistingCustomerBackendEntity extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php index 25108d19534..15a132e59b0 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php @@ -30,7 +30,6 @@ class CreateExistingCustomerFrontendEntity extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php index 7943a1d9932..aa4a6e2c7ce 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php @@ -30,7 +30,6 @@ class DeleteCustomerAddressTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php index c22526ed1a0..ed2a080882e 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php @@ -32,7 +32,6 @@ class DeleteCustomerBackendEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php index 0622ceb028f..d0bf918b5e0 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php @@ -31,7 +31,6 @@ class DeleteCustomerGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php index 5d264933336..6176e5f2d42 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php @@ -24,7 +24,6 @@ class DeleteSystemCustomerGroupTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php index 67afe99b202..d95a215fb91 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php @@ -27,7 +27,6 @@ class ForgotPasswordOnFrontendTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php index de458ff0a8b..8369533ed43 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php @@ -36,7 +36,6 @@ class MassAssignCustomerGroupTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php index 37431c7878e..43efeaaaca4 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php @@ -34,7 +34,6 @@ class MassDeleteCustomerBackendEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php index b5be83035f0..2dcd57ac0eb 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php @@ -27,7 +27,6 @@ class RegisterCustomerFrontendEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php index fcc523db65c..4baa9985742 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php @@ -31,7 +31,6 @@ class UpdateCustomerBackendEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php index c3b50d4371f..888067ac0ed 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php @@ -38,7 +38,6 @@ class UpdateCustomerFrontendEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php index 548333915c6..377e1b1fd4b 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php @@ -32,7 +32,6 @@ class UpdateCustomerGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php index 243b8564481..c29189cd14a 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php @@ -24,7 +24,6 @@ class VerifyDisabledCustomerGroupFieldTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php index 15567c4ef8d..ccd3add8e90 100644 --- a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php @@ -31,7 +31,6 @@ class CreateCurrencyRateTest extends Injectable { /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php index 117f0454877..8ef9493728d 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php @@ -30,7 +30,6 @@ class CreateDownloadableProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php index 6eb17b87a74..72797c10db5 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php @@ -37,7 +37,6 @@ class UpdateDownloadableProductEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php index 4d349580bd7..8b151965212 100644 --- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php +++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php @@ -29,7 +29,6 @@ class CheckoutWithGiftMessagesTest extends Scenario { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; const TO_MAINTAIN = 'yes'; // Consider variation #2 to work correctly with Virtual products /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php index 7126dfa00a9..df5f8485f0b 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php @@ -37,7 +37,6 @@ class CreateGroupedProductEntityTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php index 36c67db2ec3..fa90eeca3e6 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php @@ -30,7 +30,6 @@ class UpdateGroupedProductEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php index b6e81512c9f..36403cb8e25 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php @@ -27,7 +27,6 @@ class ActivateIntegrationEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php index 53e6c9fef13..a8ab81ded70 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php @@ -27,7 +27,6 @@ class CreateIntegrationEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php index 2f5b450f7bd..91e18055a87 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php @@ -30,7 +30,6 @@ class CreateIntegrationWithDuplicatedNameTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php index 894cdccadd6..1915399a87f 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php @@ -28,7 +28,6 @@ class DeleteIntegrationEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php index ed373ed2a58..c844d8a34e9 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php @@ -30,7 +30,6 @@ class ReAuthorizeTokensIntegrationEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php index fc246582127..b1e52bdf725 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php @@ -30,7 +30,6 @@ class UpdateIntegrationEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php index 976d52fb0f1..6e4ed481161 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php @@ -26,7 +26,6 @@ use Magento\Mtf\TestCase\Injectable; class FilterProductListTest extends Injectable { /* tags */ - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php b/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php index 19332e899e1..855bbfb5136 100644 --- a/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php +++ b/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php @@ -19,7 +19,6 @@ use Magento\Mtf\TestCase\Injectable; class ApplyMapTest extends Injectable { /* tags */ - const DOMAIN = 'MX'; const MVP = 'yes'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php index 99d9fff1465..0fe5fdab870 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php @@ -31,7 +31,6 @@ class ActionNewsletterTemplateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php index 314670ad2d1..d1a6b448e60 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php @@ -29,7 +29,6 @@ class CreateNewsletterTemplateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php index bd30c443ca0..6ab2d72c265 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php @@ -32,7 +32,6 @@ class PreviewNewsletterTemplateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php index ed27d43681e..5bc3a932442 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php @@ -34,7 +34,6 @@ class UpdateNewsletterTemplateTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php index af7cdfc6997..8fd543d88a8 100644 --- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php +++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php @@ -22,7 +22,6 @@ class FlushAdditionalCachesTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php index f07546b1006..28090b86629 100644 --- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php +++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php @@ -21,7 +21,6 @@ class FlushStaticFilesCacheButtonVisibilityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php index be6c223a250..92f009ef449 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php @@ -29,7 +29,6 @@ class ExpressCheckoutFromProductPageTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; const TO_MAINTAIN = 'yes'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php index fc85feb524b..ec6c87b0e3f 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php @@ -29,7 +29,6 @@ class ExpressCheckoutFromShoppingCartTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; const TO_MAINTAIN = 'yes'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php index f57544ae5a6..67715c1c575 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php @@ -33,7 +33,6 @@ class ExpressCheckoutOnePageTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; const TO_MAINTAIN = 'yes'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php index 9637d95a721..453ab8f96af 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php @@ -30,7 +30,6 @@ class InContextExpressCheckoutFromShoppingCartTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; const TO_MAINTAIN = 'yes'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php index 1cc9e00df7e..b9e794bd8f4 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php @@ -30,7 +30,6 @@ class InContextExpressOnePageCheckoutTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; const TO_MAINTAIN = 'yes'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php index e0fff16f9cb..297b6f6de18 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php @@ -32,7 +32,6 @@ class AddProductVideoTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php index 63f3fa8f4f4..7ebf84fb47c 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php @@ -34,7 +34,6 @@ class DeleteProductVideoTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php index b6c4fdc25dc..6821eceef3f 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php @@ -35,7 +35,6 @@ class UpdateProductVideoTest extends Injectable /* tags */ const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php index 20feecc8a54..4ad19088c68 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php @@ -34,7 +34,6 @@ class AbandonedCartsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php index 317ea3cd16c..f4236137c0e 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php @@ -31,7 +31,6 @@ class BestsellerProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php index 208fba464a3..ef5eec6e4e9 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php @@ -42,7 +42,6 @@ class CustomerReviewReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php index e27ddbd5be6..5b43485a8a6 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php @@ -31,7 +31,6 @@ class CustomersOrderCountReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php index fe4454065b7..13c92bfde8a 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php @@ -31,7 +31,6 @@ class CustomersOrderTotalReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php index 97ea72404ec..ec7a335f0d5 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php @@ -32,7 +32,6 @@ class DownloadProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php index b925a6f049c..32d6c457f2a 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php @@ -25,7 +25,6 @@ class LowStockProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php index 2c24ef791c6..b3f0f2c244f 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php @@ -30,7 +30,6 @@ class NewAccountsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php index ca1b3594b11..bd231c47a35 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php @@ -28,7 +28,6 @@ class OrderedProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php index cdc7f443132..b92a5fba541 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php @@ -26,7 +26,6 @@ class ProductReviewReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** 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 fb8007bc244..d8b71bf1105 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 @@ -32,7 +32,6 @@ class ProductsInCartReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php index de3f9e60f3f..fb1da56b4a9 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php @@ -34,7 +34,6 @@ class SalesCouponReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php index 6e480ca94bc..e58aaafb7f9 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php @@ -37,7 +37,6 @@ class SalesInvoiceReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php index 014148b561e..a35e3cef096 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php @@ -37,7 +37,6 @@ class SalesOrderReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php index 2b411a19c22..e2ba3387a18 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php @@ -36,7 +36,6 @@ class SalesRefundsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php index 844a30bed98..2c9d818c777 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php @@ -41,7 +41,6 @@ class SalesTaxReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php index 69ed5fbce7d..85b202ea21b 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php @@ -28,7 +28,6 @@ class SearchTermsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php index 3f45a0541fe..8550dffcf1b 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php @@ -33,7 +33,6 @@ class ViewedProductsReportEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php index f25b46c5312..047ae6521e5 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php @@ -32,7 +32,6 @@ class CreateProductRatingEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php index d7de5f52103..1677daf7820 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php @@ -34,7 +34,6 @@ class CreateProductReviewBackendEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php index fa46c5d5158..73a5ee2dce6 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php @@ -34,7 +34,6 @@ class CreateProductReviewFrontendEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php index 71fcc265d9a..aee8ef840c6 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php @@ -31,7 +31,6 @@ class DeleteProductRatingEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php index 09ed2350b0c..2f673bcfce4 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php @@ -43,7 +43,6 @@ class ManageProductReviewFromCustomerPageTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php index 0cc043c4c33..fb73765357a 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php @@ -33,7 +33,6 @@ class MassActionsProductReviewEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php index d0dcf9a14eb..a97b9961c97 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php @@ -31,7 +31,6 @@ class ModerateProductReviewEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php index 555217246c6..e099a313164 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php @@ -36,7 +36,6 @@ class UpdateProductReviewEntityOnProductPageTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php index e82f3637a13..478dae48d35 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php @@ -34,7 +34,6 @@ class UpdateProductReviewEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php index 62bc18ee07f..5898f9bce90 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php @@ -37,7 +37,6 @@ class AssignCustomOrderStatusTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php index 91f697e332b..f1096549f8e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php @@ -31,7 +31,6 @@ class CancelCreatedOrderTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php index 57f18d9e864..c74c1c460e3 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php @@ -32,7 +32,6 @@ class CreateCreditMemoEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php index 66ddf31ca0e..1dc12dc31f1 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php @@ -27,7 +27,6 @@ class CreateCustomOrderStatusEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php index 1bde546b2d6..e4fe93a72e1 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php @@ -30,7 +30,6 @@ class CreateInvoiceEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php index c871d382fbe..ef2f4f038af 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php @@ -39,7 +39,6 @@ class CreateOnlineInvoiceEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php index c5bd68ab71c..1784204e8de 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php @@ -34,7 +34,6 @@ class CreateOrderBackendTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test, 3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php index 9e6b2c9556a..afd87907872 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php @@ -31,7 +31,6 @@ class HoldCreatedOrderTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php index 5735c266251..9eff5d2f8ce 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php @@ -29,7 +29,6 @@ class MassOrdersUpdateTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php index 7c41d7c1894..cb64304341e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php @@ -33,7 +33,6 @@ class MoveLastOrderedProductsOnOrderPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php index 6cfeabdd056..1997f0cc8c3 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php @@ -39,7 +39,6 @@ class MoveProductsInComparedOnOrderPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php index cd95ec1479e..3a2c1af1ef6 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php @@ -40,7 +40,6 @@ class MoveRecentlyComparedProductsOnOrderPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php index 0118c2cdcc8..1942a2f4ce3 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php @@ -35,7 +35,6 @@ class MoveRecentlyViewedProductsOnOrderPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** 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 628cfa08716..6238e41b9c3 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 @@ -38,7 +38,6 @@ class MoveShoppingCartProductsOnOrderPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php index 753f4fa50c0..73eeb45164a 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php @@ -32,7 +32,6 @@ class PrintOrderFrontendGuestTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php index 0ae9f844f88..78f6cdb1354 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php @@ -28,7 +28,6 @@ class ReorderOrderEntityTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php index 85c492dcf0b..38b1a9ed562 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php @@ -28,7 +28,6 @@ class UnassignCustomOrderStatusTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php index 98726fbd9d3..4e6e3c45d0a 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php @@ -34,7 +34,6 @@ class UpdateCustomOrderStatusTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php index 30f2a1546cb..f706df29339 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php @@ -28,7 +28,6 @@ class ApplySeveralSalesRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php index 13281a69566..b419c70b740 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php @@ -34,7 +34,6 @@ class CreateSalesRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php index 7ac8c0621a4..374fc1bc542 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php @@ -29,7 +29,6 @@ class DeleteSalesRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php index 7107775cd9f..9a8e2b75231 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php @@ -12,7 +12,6 @@ class OnePageCheckoutWithDiscountTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test, 3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php index 2bf0cb6d2d5..c4c698532e7 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php @@ -31,7 +31,6 @@ class UpdateSalesRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php index 462aa845e3c..b4dedc18713 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php @@ -29,7 +29,6 @@ class CreateSynonymGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php index d11a8213a96..e43feaf2c82 100755 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php @@ -29,7 +29,6 @@ class DeleteSynonymGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php index 207e84c5ffa..8ae702052dc 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php @@ -30,7 +30,6 @@ class MergeSynonymGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php index 984984ee250..b7ae2e4b619 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php @@ -30,7 +30,6 @@ class UpdateSynonymGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php index 9a36e05e60a..cc75c27949c 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php @@ -33,7 +33,6 @@ class LockAdminUserWhenCreatingNewIntegrationTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php index 03b38c58a9a..23a43100de8 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php @@ -33,7 +33,6 @@ class LockAdminUserWhenCreatingNewRoleTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php index 03c7a33533e..c5b910c1247 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php @@ -35,7 +35,6 @@ class LockCustomerOnEditPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php index 75b06ed87b4..1612f1dac24 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php @@ -29,7 +29,6 @@ class LockCustomerOnLoginPageTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php index 57154031e70..8fdab9165db 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php @@ -25,7 +25,6 @@ class NewCustomerPasswordComplexityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php index f953be4bc5a..d3b7a3ccb13 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php @@ -27,7 +27,6 @@ class ResetCustomerPasswordFailedTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php index 8e1b0137451..0bf600a7042 100644 --- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php +++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php @@ -27,7 +27,6 @@ class ResetUserPasswordFailedTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php b/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php index 3ac010409f3..46e5a781b8a 100644 --- a/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php @@ -30,7 +30,6 @@ class CreateShipmentEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php index fbffe760eaa..021503301fe 100644 --- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php @@ -29,7 +29,6 @@ class CreateSitemapEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php index d898fd80cde..f8c9aec04c3 100644 --- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php @@ -31,7 +31,6 @@ class DeleteSitemapEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php index 4418882a8b3..80bef3298bb 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php @@ -33,7 +33,6 @@ class CreateStoreEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php index f7f5e6c6890..08a38f28843 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php @@ -29,7 +29,6 @@ class CreateStoreGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php index e2018dbdf73..8381849ecc4 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php @@ -29,7 +29,6 @@ class CreateWebsiteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php index 66d8cf55a10..3c6db84612f 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php @@ -36,7 +36,6 @@ class DeleteStoreEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php index a3980497764..d672ee72bc5 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php @@ -38,7 +38,6 @@ class DeleteStoreGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php index 5d5a068800b..7a7836f1b00 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php @@ -38,7 +38,6 @@ class DeleteWebsiteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php index 4bd993e22d3..f4d83de1df4 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php @@ -33,7 +33,6 @@ class UpdateStoreEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php index 728e1182519..4bdb0ebe71b 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php @@ -34,7 +34,6 @@ class UpdateStoreGroupEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php index 050cb3734cc..93017931d08 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php @@ -35,7 +35,6 @@ class UpdateWebsiteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php b/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php index 3a9afc21857..c8b96243a31 100644 --- a/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php +++ b/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php @@ -28,7 +28,6 @@ class SwaggerUiForRestApiTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php index 5837793ab26..426b98e3c76 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php @@ -38,7 +38,6 @@ class ApplyTaxBasedOnVatIdTest extends AbstractApplyVatIdTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php index 50a7167c207..7508aeedc0c 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php @@ -28,7 +28,6 @@ class CreateTaxRateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php index 7722a7e9773..fe32777559e 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php @@ -27,7 +27,6 @@ class CreateTaxRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php index d256fe1783a..b4731d794d2 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php @@ -31,7 +31,6 @@ class DeleteTaxRateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php index 18c4db9689b..72f7da60942 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php @@ -30,7 +30,6 @@ class DeleteTaxRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php index b6c1391a0b0..95cd136be0e 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php @@ -31,7 +31,6 @@ class TaxCalculationTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php index 7e972c17c49..c1b182f68a1 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php @@ -37,7 +37,6 @@ class TaxWithCrossBorderTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php index b0cc79aa52e..5d545d2f84f 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php @@ -33,7 +33,6 @@ class UpdateTaxRateEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php index b9cf14a74e7..6ba975ca3bc 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php @@ -32,7 +32,6 @@ class UpdateTaxRuleEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php index 57cdccd6edb..488cd1916d3 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php @@ -29,7 +29,6 @@ class GridFilteringTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php index a441bbc68c7..0174a0d8326 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php @@ -29,7 +29,6 @@ class GridFullTextSearchTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php index bfd360fbf10..f60a81c9acc 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php @@ -29,7 +29,6 @@ class GridSortingTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php index f2dddaa65ff..f80bfe520f6 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php @@ -34,7 +34,6 @@ class CreateCategoryRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php index 718d8785721..d200220b4b1 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php @@ -33,7 +33,6 @@ class CreateCustomUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php index 9c25d56bb53..aa416e8cd8d 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php @@ -34,7 +34,6 @@ class CreateProductUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php index 348d0548f1d..0109e502180 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php @@ -30,7 +30,6 @@ class DeleteCategoryUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php index e058f3c4041..417d137fd1f 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php @@ -29,7 +29,6 @@ class DeleteCustomUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php index 25fb260c1a8..bfe2171e21d 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php @@ -31,7 +31,6 @@ class DeleteProductUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php index 4361bc2a6a7..458e9381ee4 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php @@ -33,7 +33,6 @@ class UpdateCategoryUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php index 813f5b0937d..57660226ba5 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php @@ -31,7 +31,6 @@ class UpdateCustomUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php index 2ba4e53b31e..1610666be0d 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php @@ -32,7 +32,6 @@ class UpdateProductUrlRewriteEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'MX'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php index 22c82757dd4..7e0da18c990 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php @@ -30,7 +30,6 @@ class CreateAdminUserEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php index 39a11c0c169..4176ade9a19 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php @@ -27,7 +27,6 @@ class CreateAdminUserRoleEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php index 65f0443812d..eea19670d5a 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php @@ -34,7 +34,6 @@ class DeleteAdminUserEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php index 7282818399d..c32c63e16b4 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php @@ -35,7 +35,6 @@ class DeleteUserRoleEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php index a14273d7f94..88ccb829a89 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php @@ -31,7 +31,6 @@ class LockAdminUserEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php index e6139c681d2..0a2b6a8d151 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php @@ -34,7 +34,6 @@ class RevokeAllAccessTokensForAdminWithoutTokensTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php index c3b65ce1ca9..8ea332373a5 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php @@ -34,7 +34,6 @@ class UpdateAdminUserEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php index dc417cfa96d..40c5f48864c 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php @@ -34,7 +34,6 @@ class UpdateAdminUserRoleEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php index 235d078b283..98c7e8a27d7 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php @@ -43,7 +43,6 @@ class UserLoginAfterChangingPermissionsTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php index ff441a0ec57..c9cdee72fdf 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php @@ -27,7 +27,6 @@ class CreateCustomVariableEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php index 88bc18a71bc..79b9a359bcb 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php @@ -29,7 +29,6 @@ class DeleteCustomVariableEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php index 4f3b82b26dd..be1765e573a 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php @@ -36,7 +36,6 @@ class UpdateCustomVariableEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php index 37d0fdc81c5..474b81ccac0 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php @@ -37,7 +37,6 @@ class CreateVaultOrderBackendTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'acceptance_test, extended_acceptance_test, 3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php index 7d5e6d8284f..ea06b9b3345 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php @@ -30,7 +30,6 @@ class DeleteSavedCreditCardTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php index 357dca735c9..6795c595adc 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php @@ -35,7 +35,6 @@ class ReorderUsingVaultTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test, 3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php index 39332d9c657..7ea8aa311fd 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php @@ -38,7 +38,6 @@ class UseVaultOnCheckoutTest extends Scenario { /* tags */ const MVP = 'yes'; - const DOMAIN = 'CS'; const TEST_TYPE = '3rd_party_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php index 5f3d91b58d1..d214913fe6d 100644 --- a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php +++ b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php @@ -48,7 +48,6 @@ class CreateTaxWithFptTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php index 46383765d25..71d341acf32 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php @@ -25,7 +25,6 @@ class CreateWidgetEntityTest extends AbstractCreateWidgetEntityTest { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php index f9426890212..4a45f8514f0 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php @@ -29,7 +29,6 @@ class DeleteWidgetEntityTest extends Injectable { /* tags */ const MVP = 'yes'; - const DOMAIN = 'PS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php index 6804bdfa464..0c072ba9130 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php @@ -28,7 +28,6 @@ class AddProductToWishlistEntityTest extends AbstractWishlistTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php index 1a145f4a06c..a8ab45a4764 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php @@ -28,7 +28,6 @@ class AddProductsToCartFromCustomerWishlistOnFrontendTest extends AbstractWishli { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php index ed0f91570a6..710580ad811 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php @@ -33,7 +33,6 @@ class ConfigureProductInCustomerWishlistOnBackendTest extends AbstractWishlistTe { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php index 2abae352944..1d227e86451 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php @@ -29,7 +29,6 @@ class ConfigureProductInCustomerWishlistOnFrontendTest extends AbstractWishlistT { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php index 2699153ef9a..a043e2669e4 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php @@ -34,7 +34,6 @@ class DeleteProductFromCustomerWishlistOnBackendTest extends AbstractWishlistTes { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php index 9705358cba5..9dd4ee579b3 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php @@ -27,7 +27,6 @@ class DeleteProductsFromWishlistOnFrontendTest extends AbstractWishlistTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php index 33c47f44069..a9dca80c478 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php @@ -28,7 +28,6 @@ class MoveProductFromShoppingCartToWishlistTest extends AbstractWishlistTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; const TEST_TYPE = 'extended_acceptance_test'; /* end tags */ diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php index fd8abbe0644..30f18cdd8a8 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php @@ -35,7 +35,6 @@ class ShareWishlistEntityTest extends Injectable { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php index b1736c332b0..5ff9f3871e4 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php @@ -32,7 +32,6 @@ class ViewProductInCustomerWishlistOnBackendTest extends AbstractWishlistTest { /* tags */ const MVP = 'no'; - const DOMAIN = 'CS'; /* end tags */ /** -- GitLab From 1ecb58a96e999784aca9ca1269eb5725063fc1c3 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Wed, 3 Aug 2016 11:44:27 -0500 Subject: [PATCH 124/838] MAGETWO-56098: New static test for the changed modules - Added test. - Fixed instances found by test. --- .../view/frontend/templates/form.phtml | 2 +- .../frontend/templates/html/notices.phtml | 8 ++-- .../frontend/templates/require_cookie.phtml | 2 +- .../view/frontend/templates/remember_me.phtml | 4 +- .../Rss/view/frontend/templates/feeds.phtml | 6 +-- .../view/frontend/templates/send.phtml | 4 +- .../customer/edit/tab/wishlist.phtml | 4 +- .../renderer/actions/move_to_wishlist.phtml | 2 +- .../catalog/product/list/addto/wishlist.phtml | 2 +- .../catalog/product/view/addto/wishlist.phtml | 4 +- .../frontend/templates/item/column/cart.phtml | 2 +- .../frontend/templates/item/column/edit.phtml | 2 +- .../templates/item/column/image.phtml | 2 +- .../frontend/templates/item/column/name.phtml | 2 +- .../templates/item/column/remove.phtml | 2 +- .../templates/item/configure/addto.phtml | 6 +-- .../item/configure/addto/wishlist.phtml | 4 +- .../view/frontend/templates/rss/email.phtml | 2 +- .../frontend/templates/rss/wishlist.phtml | 2 +- .../view/frontend/templates/shared.phtml | 12 ++--- .../view/frontend/templates/sharing.phtml | 4 +- .../view/frontend/templates/sidebar.phtml | 2 +- .../view/frontend/templates/view.phtml | 6 +-- .../Magento/Test/Php/XssPhtmlTemplateTest.php | 44 +++++++++++++++++++ 24 files changed, 87 insertions(+), 43 deletions(-) diff --git a/app/code/Magento/Contact/view/frontend/templates/form.phtml b/app/code/Magento/Contact/view/frontend/templates/form.phtml index 63cf1929e38..8b8cd9171b2 100644 --- a/app/code/Magento/Contact/view/frontend/templates/form.phtml +++ b/app/code/Magento/Contact/view/frontend/templates/form.phtml @@ -8,7 +8,7 @@ ?> <form class="form contact" - action="<?php /* @escapeNotVerified */ echo $block->getFormAction(); ?>" + action="<?php echo $block->escapeUrl($block->getFormAction()); ?>" id="contact-form" method="post" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 0ef6e395c03..b0ec33d199d 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -27,10 +27,10 @@ "#notice-cookie-block": { "cookieNotices": { "cookieAllowButtonSelector": "#btn-cookie-allow", - "cookieName": "<?php /* @escapeNotVerified */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", - "cookieValue": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, - "cookieLifetime": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>, - "noCookiesUrl": "<?php /* @escapeNotVerified */ echo $block->getUrl('cookie/index/noCookies') ?>" + "cookieName": "<?php echo $block->escapeJs(\Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE) ?>", + "cookieValue": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, + "cookieLifetime": <?php echo $block->escapeJs($this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()) ?>, + "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" } } } diff --git a/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml b/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml index dd3f56da745..5f5a318364b 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/require_cookie.phtml @@ -8,7 +8,7 @@ <script type="text/x-magento-init"> { "body": { - "requireCookie": <?php /* @escapeNotVerified */ echo $block->getScriptOptions(); ?> + "requireCookie": <?php /* @noEscape */ echo $block->getScriptOptions(); ?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml index c233b54e129..88de4429095 100644 --- a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml +++ b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml @@ -16,8 +16,8 @@ ?> <div id="remember-me-box" class="field choice persistent"> <?php $rememberMeId = 'remember_me' . $block->getRandomString(10); ?> - <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php /* @escapeNotVerified */ echo $rememberMeId; ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> - <label for="<?php /* @escapeNotVerified */ echo $rememberMeId; ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> + <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> + <label for="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> <span class="tooltip wrapper"> <a class="link tooltip toggle" href="#"><?php /* @escapeNotVerified */ echo __('What\'s this?') ?></a> <span class="tooltip content"> diff --git a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml index 81ac6fd8032..d31dc5c1663 100644 --- a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml +++ b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml @@ -16,16 +16,16 @@ <tr> <td class="col feed"><?php echo $block->escapeHtml($feed['label']) ?></td> <td class="col action"> - <a href="<?php /* @escapeNotVerified */ echo $feed['link'] ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> + <a href="<?php echo $block->escapeUrl($feed['link']) ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> </td> </tr> <?php else: ?> - <th colspan="2" scope="col"><?php /* @escapeNotVerified */ echo $feed['group'] ?></th> + <th colspan="2" scope="col"><?php echo $block->escapeHtml($feed['group']) ?></th> <?php foreach ($feed['feeds'] as $item) :?> <tr> <td class="col feed"><?php echo $block->escapeHtml($item['label']) ?></td> <td class="col action"> - <a href="<?php /* @escapeNotVerified */ echo $item['link'] ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> + <a href="<?php echo $block->escapeUrl($item['link']) ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> </td> </tr> <?php endforeach; ?> diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index a2999fe95d0..0544bb75f89 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -41,7 +41,7 @@ </fieldset> </script> -<form action="<?php /* @escapeNotVerified */ echo $block->getSendUrl() ?>" method="post" id="product-sendtofriend-form" +<form action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" method="post" id="product-sendtofriend-form" data-mage-init='{ "rowBuilder":{ "rowTemplate":"#add-recipient-tmpl", @@ -49,7 +49,7 @@ "rowParentElem":"<div></div>", "remEventSelector":"button", "btnRemoveSelector":".action.remove", - "maxRows":"<?php /* @escapeNotVerified */ echo $block->getMaxRecipients() ?>", + "maxRows":"<?php echo (int) $block->getMaxRecipients() ?>", "maxRowsMsg":"#max-recipient-message", "addRowBtn":"#add-recipient-button", "additionalRowClass":"additional"}, diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index 334401d8ec0..5182d016d5e 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -65,8 +65,8 @@ productConfigure.addListType( 'wishlist', { - urlFetch: '<?php /* @escapeNotVerified */ echo $block->getUrl('customer/wishlist_product_composite_wishlist/configure') ?>', - urlConfirm: '<?php /* @escapeNotVerified */ echo $block->getUrl('customer/wishlist_product_composite_wishlist/update') ?>' + urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/configure')) ?>', + urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/update')) ?>' } ); //--> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml index e115b71ba84..7535c12326a 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml @@ -10,7 +10,7 @@ ?> <?php if ($block->isAllowInCart() && $block->isProductVisibleInSiteVisibility()): ?> <a href="#" - data-post='<?php /* @escapeNotVerified */ echo $block->getMoveFromCartParams(); ?>' + data-post='<?php /* @noEscape */ echo $block->getMoveFromCartParams(); ?>' class="use-ajax action action-towishlist"> <span><?php /* @noEscape */ echo __('Move to Wishlist'); ?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index a618788dfd8..cc6b6596d9b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -12,7 +12,7 @@ class="action towishlist" title="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>" aria-label="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>" - data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' + data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' data-action="add-to-wishlist" role="button"> <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml index 1062df9eb44..b1b88dc408d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml @@ -11,13 +11,13 @@ <?php if ($block->isWishListAllowed()) : ?> <a href="#" class="action towishlist" - data-post='<?php /* @escapeNotVerified */ echo $block->getWishlistParams(); ?>' + data-post='<?php /* @noEscape */ echo $block->getWishlistParams(); ?>' data-action="add-to-wishlist"><span><?php /* @noEscape */ echo __('Add to Wish List') ?></span></a> <?php endif; ?> <script type="text/x-magento-init"> { "body": { - "addToWishlist": <?php /* @escapeNotVerified */ echo $block->getWishlistOptionsJson() ?> + "addToWishlist": <?php /* @noEscape */ echo $block->getWishlistOptionsJson() ?> } } </script> 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 da6f4f86917..57319c98b50 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 @@ -28,7 +28,7 @@ $product = $item->getProduct(); <?php if ($product->isSaleable()): ?> <div class="product-item-actions"> <div class="actions-primary"> - <button type="button" data-role="tocart" data-post='<?php /* @escapeNotVerified */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtml($item->getId())?>" class="action tocart primary"> + <button type="button" data-role="tocart" data-post='<?php /* @noEscape */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @noEscape */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtml($item->getId())?>" class="action tocart primary"> <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> </button> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index ac33424138a..35a6dee335b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -12,7 +12,7 @@ $product = $item->getProduct(); ?> <?php if ($product->isVisibleInSiteVisibility()): ?> - <a class="action edit" href="<?php /* @escapeNotVerified */ echo $block->getItemConfigureUrl($item) ?>"> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getItemConfigureUrl($item)) ?>"> <span><?php /* @noEscape */ echo __('Edit') ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml index 77a6122499c..c0a0d6e5497 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml @@ -10,6 +10,6 @@ $item = $block->getItem(); $product = $item->getProduct(); ?> -<a class="product-item-photo" href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> +<a class="product-item-photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> <?php echo $block->getImage($product, 'wishlist_thumbnail')->toHtml(); ?> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml index 5a8cf4ba5b6..261d1fd8aba 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml @@ -11,7 +11,7 @@ $item = $block->getItem(); $product = $item->getProduct(); ?> <strong class="product-item-name"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>" class="product-item-link"> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>" class="product-item-link"> <?php echo $block->escapeHtml($product->getName()) ?> </a> </strong> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index cf803bbad06..62837f3cbdf 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -10,6 +10,6 @@ ?> -<a href="#" data-role="remove" data-post-remove='<?php /* @escapeNotVerified */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @noEscape */ echo __('Remove Item') ?>" class="btn-remove action delete"> +<a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @noEscape */ echo __('Remove Item') ?>" class="btn-remove action delete"> <span><?php /* @noEscape */ echo __('Remove item');?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml index 3333c68561f..6cfd002f738 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml @@ -12,14 +12,14 @@ <div class="product-addto-links" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <?php $_product = $block->getProduct(); ?> <?php $_compareUrl = $this->helper('Magento\Catalog\Helper\Product\Compare')->getAddUrl($_product); ?> <?php if ($_compareUrl) : ?> - <a href="<?php /* @escapeNotVerified */ echo $_compareUrl ?>" class="action tocompare"> + <a href="<?php echo $block->escapeUrl($_compareUrl) ?>" class="action tocompare"> <span><?php /* @noEscape */ echo __('Add to Compare') ?></span> </a> <?php endif; ?> @@ -27,7 +27,7 @@ <script type="text/x-magento-init"> { "body": { - "addToWishlist": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> + "addToWishlist": <?php /* @noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml index f757672f931..7106b30425c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml @@ -9,14 +9,14 @@ /** @var $block \Magento\Wishlist\Block\Catalog\Product\View\Addto\Wishlist */ ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> <span><?php /* @noEscape */ echo __('Update Wish List') ?></span> </a> <?php endif; ?> <script type="text/x-magento-init"> { "body": { - "addToWishlist": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> + "addToWishlist": <?php /* @noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getWishlistOptions())?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml index f7290fe43f1..54eac70c29b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml @@ -12,6 +12,6 @@ <p style="font-size:12px; line-height:16px; margin:0 0 16px;"> <?php echo __("RSS link to %1's wishlist", $block->escapeHtml($this->helper('Magento\Wishlist\Helper\Data')->getCustomerName())) ?> <br /> - <a href="<?php /* @escapeNotVerified */ echo $block->getLink(); ?>"><?php /* @escapeNotVerified */ echo $block->getLink(); ?></a> + <a href="<?php echo $block->escapeUrl($block->getLink()); ?>"><?php echo $block->escapeUrl($block->getLink()); ?></a> </p> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml index c44b3ea13dc..459dec68740 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml @@ -9,7 +9,7 @@ /* @var $block \Magento\Wishlist\Block\Rss\Link */ ?> <?php if ($block->isRssAllowed() && $block->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?> - <a href="<?php /* @escapeNotVerified */ echo $block->getLink(); ?>" class="action rss wishlist"> + <a href="<?php echo $block->escapeUrl($block->getLink()); ?>" class="action rss wishlist"> <span><?php /* @noEscape */ echo __('RSS Feed') ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index e7d1bc86825..49e3487f78b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -10,7 +10,7 @@ ?> <?php if ($block->hasWishlistItems()): ?> - <form class="form shared wishlist" action="<?php /* @escapeNotVerified */ echo $block->getUrl('wishlist/index/update') ?>" method="post"> + <form class="form shared wishlist" action="<?php echo $block->escapeUrl($block->getUrl('wishlist/index/update')) ?>" method="post"> <div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> <caption class="table-caption"><?php /* @noEscape */ echo __('Wish List'); ?></caption> @@ -29,11 +29,11 @@ ?> <tr> <td data-th="<?php echo $block->escapeHtml(__('Product')) ?>" class="col product"> - <a class="product photo" href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> + <a class="product photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtml($product->getName()) ?>"> <?php echo $block->getImage($product, 'customer_shared_wishlist')->toHtml(); ?> </a> <strong class="product name"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($item) ?>"> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>"> <?php echo $block->escapeHtml($product->getName()) ?> </a> </strong> @@ -53,13 +53,13 @@ <?php if ($isVisibleProduct): ?> <button type="button" title="<?php /* @noEscape */ echo __('Add to Cart') ?>" - data-post='<?php /* @escapeNotVerified */ echo $block->getSharedItemAddToCartUrl($item); ?>' + data-post='<?php /* @noEscape */ echo $block->getSharedItemAddToCartUrl($item); ?>' class="action tocart"> <span><?php /* @noEscape */ echo __('Add to Cart') ?></span> </button> <?php endif ?> <?php endif; ?> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> <span><?php /* @noEscape */ echo __('Add to Wish List') ?></span> </a> </td> @@ -74,7 +74,7 @@ <div class="primary"> <button type="button" title="<?php /* @noEscape */ echo __('Add All to Cart') ?>" - data-post='<?php /* @escapeNotVerified */ echo $block->getSharedAddAllToCartUrl(); ?>' + data-post='<?php /* @noEscape */ echo $block->getSharedAddAllToCartUrl(); ?>' class="action tocart primary"> <span><?php /* @noEscape */ echo __('Add All to Cart') ?></span> </button> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index ae32b8c581a..3b436f899bd 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -9,7 +9,7 @@ /** @var $block \Magento\Wishlist\Block\Customer\Sharing */ ?> <form class="form wishlist share" - action="<?php /* @escapeNotVerified */ echo $block->getSendUrl() ?>" + action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" id="form-validate" method="post" data-hasrequired="<?php /* @noEscape */ echo __('* Required Fields') ?>" @@ -47,7 +47,7 @@ </button> </div> <div class="secondary"> - <a class="action back" href="<?php /* @escapeNotVerified */ echo $block->getBackUrl(); ?>"><span><?php /* @noEscape */ echo __('Back')?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"><span><?php /* @noEscape */ echo __('Back')?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml index c333deb1923..541d7a6c181 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml @@ -61,7 +61,7 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <div class="actions-toolbar no-display" data-bind="css: {'no-display': null}"> <div class="primary"> <a class="action details" - href="<?php /* @escapeNotVerified */ echo $this->helper('Magento\Wishlist\Helper\Data')->getListUrl() ?>" + href="<?php echo $block->escapeUrl($this->helper('Magento\Wishlist\Helper\Data')->getListUrl()) ?>" title="<?php /* @noEscape */ echo __('Go to Wish List') ?>"><span><?php /* @noEscape */ echo __('Go to Wish List') ?></span></a> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml index 5f2eef48307..d26266ae723 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml @@ -13,10 +13,10 @@ <?php echo($block->getChildHtml('wishlist.rss.link'));?> <form class="form-wishlist-items" id="wishlist-view-form" data-mage-init='{"wishlist":{ - "addToCartUrl":<?php /* @escapeNotVerified */ echo $block->getItemAddToCartParams("%item%");?>, - "addAllToCartUrl":<?php /* @escapeNotVerified */ echo $block->getAddAllToCartParams(); ?>, + "addToCartUrl":<?php /* @noEscape */ echo $block->getItemAddToCartParams("%item%");?>, + "addAllToCartUrl":<?php /* @noEscape */ echo $block->getAddAllToCartParams(); ?>, "commentString":""}, - "validation": {}}' action="<?php /* @escapeNotVerified */ echo $block->getUrl('wishlist/index/update', ['wishlist_id' => $block->getWishlistInstance()->getId()]) ?>" method="post"> + "validation": {}}' action="<?php echo $block->escapeUrl($block->getUrl('wishlist/index/update', ['wishlist_id' => $block->getWishlistInstance()->getId()])) ?>" method="post"> <?php echo $block->getChildHtml('top'); ?> <?php if ($block->hasWishlistItems()): ?> <?php echo $block->getBlockHtml('formkey');?> diff --git a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php index 33db1aeee6c..599bb4288d3 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php @@ -8,12 +8,30 @@ namespace Magento\Test\Php; use Magento\Framework\App\Utility\Files; use Magento\TestFramework\Utility\XssOutputValidator; +use Magento\Framework\Component\ComponentRegistrar; /** * Find not escaped output in phtml templates */ class XssPhtmlTemplateTest extends \PHPUnit_Framework_TestCase { + /** + * @var array + */ + private $moduleList = [ + 'Magento_Customer', + 'Magento_Contact', + 'Magento_Cookie', + 'Magento_Customer', + 'Magento_Newsletter', + 'Magento_Persistent', + 'Magento_ProductAlert', + 'Magento_Review', + 'Magento_Rss', + 'Magento_Wishlist', + 'Magento_SendFriend' + ]; + /** * @return void */ @@ -50,4 +68,30 @@ class XssPhtmlTemplateTest extends \PHPUnit_Framework_TestCase Files::init()->getPhtmlFiles() ); } + + /** + * @return void + */ + public function testAbsenceOfEscapeNotVerifiedAnnotationInRefinedModules() + { + $componentRegistrar = new ComponentRegistrar(); + $result = ""; + foreach ($this->moduleList as $moduleName) { + $modulePath = $componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName); + foreach (Files::init()->getFiles([$modulePath], '*.phtml') as $file) { + $fileContents = file_get_contents($file); + $instances = preg_grep("/\\/* @escapeNotVerified \\*\\/ echo (?!__).+/", explode("\n", $fileContents)); + if (!empty($instances)) { + foreach (array_keys($instances) as $line) { + $result .= $file . ':' . ($line + 1) . "\n"; + } + } + } + } + $this->assertEmpty( + $result, + "@escapeNotVerified annotation detected.\n" . + "Please use the correct escape strategy and remove annotation at : \n" . $result + ); + } } -- GitLab From 984e2b66e5e0e66aa47290123610822e0b63264f Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Wed, 3 Aug 2016 11:47:56 -0500 Subject: [PATCH 125/838] MAGETWO-56098: New static test for the changed modules - A line was over 80 chars. --- .../static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php index 599bb4288d3..bbe5286c8fb 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php @@ -80,7 +80,8 @@ class XssPhtmlTemplateTest extends \PHPUnit_Framework_TestCase $modulePath = $componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName); foreach (Files::init()->getFiles([$modulePath], '*.phtml') as $file) { $fileContents = file_get_contents($file); - $instances = preg_grep("/\\/* @escapeNotVerified \\*\\/ echo (?!__).+/", explode("\n", $fileContents)); + $pattern = "/\\/* @escapeNotVerified \\*\\/ echo (?!__).+/"; + $instances = preg_grep($pattern, explode("\n", $fileContents)); if (!empty($instances)) { foreach (array_keys($instances) as $line) { $result .= $file . ':' . ($line + 1) . "\n"; -- GitLab From 92e0043f36f93d603a00d195601b34b1bb9213d5 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 13:18:32 -0500 Subject: [PATCH 126/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- .../adminhtml/templates/rating/detailed.phtml | 2 ++ .../adminhtml/templates/rating/options.phtml | 29 ------------------- .../templates/rating/stars/detailed.phtml | 25 ---------------- .../templates/rating/stars/summary.phtml | 1 + .../frontend/templates/customer/list.phtml | 1 + .../frontend/templates/customer/recent.phtml | 6 +--- .../frontend/templates/customer/view.phtml | 4 +-- .../view/frontend/templates/detailed.phtml | 1 + .../Review/view/frontend/templates/form.phtml | 4 +-- .../frontend/templates/helper/summary.phtml | 6 ++-- .../templates/helper/summary_short.phtml | 6 ++-- .../templates/product/view/list.phtml | 14 +++------ .../templates/product/view/other.phtml | 3 +- .../view/frontend/templates/review.phtml | 3 +- 14 files changed, 24 insertions(+), 81 deletions(-) delete mode 100644 app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml delete mode 100644 app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml index 089fd7a3dc1..89073febf02 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Adminhtml\Rating\Detailed $block */ + ?> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> <?php foreach ($block->getRating() as $_rating): ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml deleted file mode 100644 index b0712f11dec..00000000000 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml +++ /dev/null @@ -1,29 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -?> -<div class="entry-edit-head"> - <h4 class="icon-head head-edit-form fieldset-legend"><?php /* @escapeNotVerified */ echo __('Assigned Options') ?></h4> -</div> -<fieldset id="options_form"> -<?php if (!$options): ?> - <?php for ($_i = 1;$_i <= 5;$_i++): ?> - <span class="field-row"> - <label for="option_<?php /* @noEscape */ echo $_i ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> - <input id="option_<?php /* @noEscape */ echo $_i ?>" name="option[<?php /* @noEscape */ echo $_i ?>][code]" value="<?php /* @noEscape */ echo $_i ?>" class="input-text" type="text" /> - </span> - <?php endfor; ?> -<?php elseif ($options->getSize() > 0): ?> - <?php foreach ($options->getItems() as $_item): ?> - <span class="field-row"> - <label for="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> - <input id="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>" name="option[<?php echo $block->escapeHtmlAttr($_item->getId()) ?>][code]" value="<?php echo $block->escapeHtmlAttr($_item->getCode()) ?>" class="input-text" type="text" /> - </span> - <?php endforeach; ?> -<?php endif; ?> -</fieldset> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml deleted file mode 100644 index bdc65c0fbbf..00000000000 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -?> -<?php if ($block->getRating() && $block->getRating()->getSize()): ?> - <div class="ratings-container"> - <?php foreach ($block->getRating() as $_rating): ?> - <?php if ($_rating->getPercent()): ?> - <div class="ratings"> - <?php echo $block->escapeHtml($_rating->getRatingCode()) ?> - <div class="rating-box"> - <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getPercent()) ?>%;"></div> - </div> - </div> - <?php endif; ?> - <?php endforeach; ?> - </div> -<?php else: ?> - <?php /* @escapeNotVerified */ echo __("Rating isn't Available") ?> -<?php endif; ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml index 292cea00da6..1badd869907 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml @@ -6,6 +6,7 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Adminhtml\Rating\Summary $block */ ?> <?php if ($block->getRatingSummary()->getCount()): ?> <div class="rating-box"> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index e3d8aad8bc9..9eb6259230d 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -5,6 +5,7 @@ */ // @codingStandardsIgnoreFile + /** @var \Magento\Review\Block\Customer\ListCustomer $block */ ?> <?php if ($block->getReviews() && count($block->getReviews())): ?> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml index 2cc7a20bc3a..b232b832b86 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml @@ -6,12 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Customer\Recent $block */ ?> - -<?php -/** @var $block \Magento\Review\Block\Customer\Recent */ -?> - <?php if ($block->getReviews() && count($block->getReviews())): ?> <div class="block block-reviews-dashboard"> <div class="block-title"> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml index 64ac6d2e0e0..20172e4b546 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml @@ -6,8 +6,8 @@ // @codingStandardsIgnoreFile -?> -<?php +/** @var \Magento\Review\Block\Customer\View $block */ + $product = $block->getProductData(); ?> <?php if ($product->getId()): ?> diff --git a/app/code/Magento/Review/view/frontend/templates/detailed.phtml b/app/code/Magento/Review/view/frontend/templates/detailed.phtml index 681eb4cf66f..72bd4fcaca3 100644 --- a/app/code/Magento/Review/view/frontend/templates/detailed.phtml +++ b/app/code/Magento/Review/view/frontend/templates/detailed.phtml @@ -6,6 +6,7 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Rating\Entity\Detailed $block */ ?> <?php if (!empty($collection) && $collection->getSize()): ?> <div class="table-wrapper"> diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index a63adcce56d..ee285f3057d 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -6,9 +6,7 @@ // @codingStandardsIgnoreFile -/** - * @var $block \Magento\Review\Block\Form - */ +/** @var \Magento\Review\Block\Form $block */ ?> <div class="block review-add"> <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Write Your Own Review') ?></strong></div> diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml index 2079bed1cf8..cc5d8a0b6ae 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml @@ -6,9 +6,11 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Product\ReviewRenderer $block */ + +$url = $block->getReviewsUrl() . '#reviews'; +$urlForm = $block->getReviewsUrl() . '#review-form'; ?> -<?php $url = $block->getReviewsUrl() . '#reviews'; ?> -<?php $urlForm = $block->getReviewsUrl() . '#review-form'; ?> <?php if ($block->getReviewsCount()): ?> <?php $rating = $block->getRatingSummary(); ?> <div class="product-reviews-summary<?php echo !$rating ? ' no-rating' : ''?>" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"> diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml index df0a28de4c3..14650e7b0e0 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml @@ -6,9 +6,11 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Product\ReviewRenderer $block */ + +$url = $block->getReviewsUrl() . '#reviews'; +$urlForm = $block->getReviewsUrl() . '#review-form'; ?> -<?php $url = $block->getReviewsUrl() . '#reviews'; ?> -<?php $urlForm = $block->getReviewsUrl() . '#review-form'; ?> <?php if ($block->getReviewsCount()): ?> <?php $rating = $block->getRatingSummary(); ?> <div class="product-reviews-summary short<?php echo !$rating ? ' no-rating' : ''?>"> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml index 7e76316a210..9eb4fd10fec 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml @@ -6,16 +6,10 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * @description: - * - */ -?> -<?php - $_items = $block->getReviewsCollection()->getItems(); - $format = $block->getDateFormat() ?: \IntlDateFormatter::SHORT; +/** @var Magento\Review\Block\Product\View\ListView $block */ + +$_items = $block->getReviewsCollection()->getItems(); +$format = $block->getDateFormat() ?: \IntlDateFormatter::SHORT; ?> <?php if (count($_items)):?> <div class="block review-list" id="customer-reviews"> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml index 48222c4e8ea..3c8d626b317 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml @@ -6,9 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Product\View\Other $block */ ?> - -<?php /** @var $block \Magento\Review\Block\Product\View\Other */ ?> <?php $_product = $block->getProduct(); ?> <div class="actions"> <a href="<?php echo $block->escapeUrl($_product->getProductUrl()) ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Main Product Info') ?></span></a> diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml index 82ef2098f33..a7459ca7e1b 100644 --- a/app/code/Magento/Review/view/frontend/templates/review.phtml +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -3,8 +3,9 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -?> +/** @var \Magento\Review\Block\Product\Review $block */ +?> <div id="product-review-container" data-role="product-review"></div> <?php echo $block->getChildHtml(); ?> -- GitLab From 8bea43d57fdb01ba85a31fa841d138f79e33d05a Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 13:40:09 -0500 Subject: [PATCH 127/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../sales/order/create/address/form/renderer/vat.phtml | 4 ++-- .../adminhtml/templates/system/config/validatevat.phtml | 3 +-- .../Customer/view/adminhtml/templates/tab/cart.phtml | 3 +-- .../view/adminhtml/templates/tab/view/personal_info.phtml | 3 +-- .../Customer/view/adminhtml/templates/tab/view/sales.phtml | 4 ++-- .../frontend/templates/account/authentication-popup.phtml | 3 +-- .../frontend/templates/account/dashboard/address.phtml | 3 +-- .../view/frontend/templates/account/dashboard/info.phtml | 3 +-- .../frontend/templates/account/link/authorization.phtml | 2 +- .../Customer/view/frontend/templates/address/book.phtml | 3 +-- .../Customer/view/frontend/templates/address/edit.phtml | 3 +-- .../view/frontend/templates/form/confirmation.phtml | 3 +-- .../Customer/view/frontend/templates/form/edit.phtml | 3 +-- .../view/frontend/templates/form/forgotpassword.phtml | 3 +-- .../Customer/view/frontend/templates/form/login.phtml | 3 +-- .../Customer/view/frontend/templates/form/newsletter.phtml | 3 +-- .../Customer/view/frontend/templates/form/register.phtml | 3 +-- .../frontend/templates/form/resetforgottenpassword.phtml | 1 - .../view/frontend/templates/js/customer-data.phtml | 3 +-- .../view/frontend/templates/js/section-config.phtml | 3 +-- .../Magento/Customer/view/frontend/templates/logout.phtml | 3 +-- .../Customer/view/frontend/templates/newcustomer.phtml | 3 +-- .../Customer/view/frontend/templates/widget/dob.phtml | 2 +- .../Customer/view/frontend/templates/widget/gender.phtml | 3 +-- .../Customer/view/frontend/templates/widget/name.phtml | 2 +- .../Customer/view/frontend/templates/widget/taxvat.phtml | 7 +++---- 26 files changed, 29 insertions(+), 50 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml index 98b0556ec8e..70896e096af 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/sales/order/create/address/form/renderer/vat.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Adminhtml\Sales\Order\Address\Form\Renderer\Vat */ +/** @var \Magento\Customer\Block\Adminhtml\Sales\Order\Address\Form\Renderer\Vat $block */ $_element = $block->getElement(); $_note = $_element->getNote(); @@ -19,7 +19,7 @@ $_validateButton = $block->getValidateButton(); <div class="hidden"><?php echo $_element->getElementHtml(); ?></div> <?php else: ?> <?php echo $_element->getLabelHtml(); ?> - <div class="admin__field-control <?php /* @noEscape */ echo $_element->hasValueClass() ? $_element->getValueClass() : 'value'; ?><?php echo $_class ? " {$_class}-value" : ''; ?>"> + <div class="admin__field-control <?php /* @noEscape */ echo $_element->hasValueClass() ? $block->escapeHtmlAttr($_element->getValueClass()) : 'value'; ?><?php echo $_class ? $block->escapeHtmlAttr($_class) . '-value' : ''; ?>"> <?php echo $_element->getElementHtml(); ?> <?php if ($_note): ?> <div class="admin__field-note<?php echo $_class ? " {$_class}-note" : ''; ?>" id="note_<?php echo $block->escapeHtmlAttr($_element->getId()); ?>"> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index a08e4597b27..be1e66d94b7 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Adminhtml\System\Config\Validatevat */ - +/** @var \Magento\Customer\Block\Adminhtml\System\Config\Validatevat $block */ ?> <script> require(['prototype'], function(){ diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index 522712edf85..f8ca555c2ad 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\Cart */ - +/* @var \Magento\Customer\Block\Adminhtml\Edit\Tab\Cart $block */ ?> <?php if ($block->getCartHeader()): ?> <div class="content-header skip-header"> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml index 7c67215b5fa..4b77d2582a7 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo */ +/** @var \Magento\Customer\Block\Adminhtml\Edit\Tab\View\PersonalInfo $block */ $lastLoginDateAdmin = $block->getLastLoginDate(); $lastLoginDateStore = $block->getStoreLastLoginDate(); @@ -14,7 +14,6 @@ $lastLoginDateStore = $block->getStoreLastLoginDate(); $createDateAdmin = $block->getCreateDate(); $createDateStore = $block->getStoreCreateDate(); ?> - <div class="fieldset-wrapper customer-information"> <div class="fieldset-wrapper-title"> <span class="title"><?php /* @escapeNotVerified */ echo __('Personal Information') ?></span> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml index 5aa176fdbd8..4aef50934a5 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml @@ -6,10 +6,10 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Adminhtml\Edit\Tab\View\Sales */ +/** @var \Magento\Customer\Block\Adminhtml\Edit\Tab\View\Sales $block */ +$singleStoreMode = $block->isSingleStoreMode(); ?> -<?php $singleStoreMode = $block->isSingleStoreMode(); ?> <div class="entry-edit fieldset-wrapper"> <div class="fieldset-wrapper-title"> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index 4f7455213cf..2b62b1f6fb7 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Account\AuthenticationPopup */ - +/** @var \Magento\Customer\Block\Account\AuthenticationPopup $block */ ?> <div id="authenticationPopup" data-bind="scope:'authenticationPopup'" style="display: none;"> <script> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml index 639c469ebe4..ed6f2a835cf 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Account\Dashboard\Address */ - +/** @var \Magento\Customer\Block\Account\Dashboard\Address $block */ ?> <div class="block block-dashboard-addresses"> <div class="block-title"> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml index e67b23bb02b..7eb24b1ffe8 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Account\Dashboard\Info */ - +/** @var \Magento\Customer\Block\Account\Dashboard\Info $block */ ?> <div class="block block-dashboard-info"> <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Account Information') ?></strong></div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml index 673e5882785..a6962c20717 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Account\AuthorizationLink */ +/** @var \Magento\Customer\Block\Account\AuthorizationLink $block */ $dataPostParam = ''; if ($block->isLoggedIn()) { diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index 8dc0ec180f4..a642f8b5293 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Address\Book */ - +/** @var \Magento\Customer\Block\Address\Book $block */ ?> <div class="block block-addresses-default"> <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Default Addresses') ?></strong></div> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index 930183de2a8..dc08ef9df17 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Address\Edit */ - +/** @var \Magento\Customer\Block\Address\Edit $block */ ?> <form class="form-address-edit" action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" diff --git a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml index 33debf7276d..2dfcd7f5dd4 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Framework\View\Element\Template */ - +/** @var \Magento\Framework\View\Element\Template $block */ ?> <form action="" method="post" id="form-validate" class="form send confirmation" data-mage-init='{"validation":{}}'> <fieldset class="fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 7ec19afe026..89219df0e78 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Form\Edit */ - +/** @var \Magento\Customer\Block\Form\Edit $block */ ?> <form class="form form-edit-account" action="<?php echo $block->escapeUrl($block->getUrl('customer/account/editPost')) ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" autocomplete="off"> <fieldset class="fieldset info"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml index 2c4eaa47e07..f7f1ac86007 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml @@ -8,8 +8,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Account\Forgotpassword */ - +/** @var \Magento\Customer\Block\Account\Forgotpassword $block */ ?> <form class="form password forget" action="<?php echo $block->escapeUrl($block->getUrl('*/*/forgotpasswordpost')) ?>" diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index 7ca93787618..77335cdff76 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Form\Login */ - +/** @var \Magento\Customer\Block\Form\Login $block */ ?> <div class="block block-customer-login"> <div class="block-title"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml index 1a7f4a3eefb..51d975fc474 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Newsletter */ - +/** @var \Magento\Customer\Block\Newsletter $block */ ?> <?php echo $block->getChildHtml('form_before')?> <form class="form form-newsletter-manage" action="<?php echo $block->escapeUrl($block->getAction()) ?>" method="post" id="form-validate"> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index be6448574f6..b35727b26fb 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Form\Register */ - +/** @var \Magento\Customer\Block\Form\Register $block */ ?> <?php echo $block->getChildHtml('form_fields_before')?> <?php /* Extensions placeholder */ ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml index 868409a5fad..6b3b34fc00e 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml @@ -7,7 +7,6 @@ // @codingStandardsIgnoreFile /** @var \Magento\Customer\Block\Account\Resetpassword $block */ - ?> <form action="<?php echo $block->escapeUrl($block->getUrl('*/*/resetpasswordpost', ['_query' => ['id' => $block->getCustomerId(), 'token' => $block->getResetPasswordLinkToken()]])); ?>" method="post" diff --git a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml index 13667dabc3c..55779df1c22 100644 --- a/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/js/customer-data.phtml @@ -4,8 +4,7 @@ * See COPYING.txt for license details. */ -/** @var $block \Magento\Customer\Block\CustomerData */ - +/** @var \Magento\Customer\Block\CustomerData $block */ ?> <script type="text/x-magento-init"> <?php diff --git a/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml b/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml index 8e869d08c87..d6986829a0c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/js/section-config.phtml @@ -4,8 +4,7 @@ * See COPYING.txt for license details. */ -/** @var $block \Magento\Customer\Block\SectionConfig */ - +/** @var \Magento\Customer\Block\SectionConfig $block */ ?> <script type="text/x-magento-init"> <?php diff --git a/app/code/Magento/Customer/view/frontend/templates/logout.phtml b/app/code/Magento/Customer/view/frontend/templates/logout.phtml index c79d9a28b10..269048d618a 100644 --- a/app/code/Magento/Customer/view/frontend/templates/logout.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/logout.phtml @@ -4,8 +4,7 @@ * See COPYING.txt for license details. */ -/** @var $block \Magento\Framework\View\Element\Template */ - +/** @var \Magento\Framework\View\Element\Template $block */ ?> <p><?php /* @escapeNotVerified */ echo __('You have signed out and will go to our homepage in 5 seconds.') ?></p> <script> diff --git a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml index def74853681..7bfa236eabb 100644 --- a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Form\Login\Info */ - +/** @var \Magento\Customer\Block\Form\Login\Info $block */ ?> <?php if ($block->getRegistration()->isAllowed()): ?> <div class="block block-new-customer"> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml index 3e2e372196d..727dc43750a 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Widget\Dob */ +/** @var \Magento\Customer\Block\Widget\Dob $block */ /* <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Dob') diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml index cfe8c874beb..2c83a523d80 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Widget\Gender */ - +/** @var \Magento\Customer\Block\Widget\Gender $block */ ?> <div class="field gender<?php if ($block->isRequired()) echo ' required' ?>"> <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index d5e61ee3af7..14f464742c8 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Widget\Name */ +/** @var \Magento\Customer\Block\Widget\Name $block */ /* <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name') diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml index 54c4bf588ec..4d2b2a411d9 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml @@ -6,12 +6,11 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Customer\Block\Widget\Taxvat */ - +/** @var \Magento\Customer\Block\Widget\Taxvat $block */ ?> <div class="field taxvat<?php if ($block->isRequired()) echo ' required'; ?>"> - <label class="label" for="<?php echo $block->escapeHtml($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> <div class="control"> - <input type="text" id="<?php echo $block->escapeHtml($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtml($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> </div> </div> -- GitLab From 9f2e6ae56bd832e1ed4af381329133daf82f5a75 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 13:51:17 -0500 Subject: [PATCH 128/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- app/code/Magento/Review/view/frontend/templates/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index ee285f3057d..611416586dd 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -15,7 +15,7 @@ <form action="<?php echo $block->escapeUrl($block->getAction()) ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'"> <?php echo $block->getBlockHtml('formkey'); ?> <?php echo $block->getChildHtml('form_fields_before')?> - <fieldset class="fieldset review-fieldset" data-hasrequired="<?php __('* Required Fields'); ?>"> + <fieldset class="fieldset review-fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields'); ?>"> <legend class="legend review-legend"><span><?php /* @escapeNotVerified */ echo __("You're reviewing:"); ?></span><strong><?php echo $block->escapeHtml($block->getProductInfo()->getName()) ?></strong></legend><br /> <?php if ($block->getRatings() && $block->getRatings()->getSize()): ?> <span id="input-message-box"></span> -- GitLab From 03a6bead6b05cc781f7496244ba37bfa8fa20a83 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 14:11:07 -0500 Subject: [PATCH 129/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../view/frontend/templates/widget/gender.phtml | 2 +- .../view/frontend/templates/widget/name.phtml | 14 +++++++------- .../view/frontend/templates/widget/taxvat.phtml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml index 2c83a523d80..58cd9a7b470 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml @@ -11,7 +11,7 @@ <div class="field gender<?php if ($block->isRequired()) echo ' required' ?>"> <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> <div class="control"> - <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?> <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?>> + <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?> <?php /* @noEscape */ echo $block->getFieldParams() ?>> <?php $options = $block->getGenderOptions(); ?> <?php $value = $block->getGender();?> <?php foreach ($options as $option):?> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index 14f464742c8..336f89914b5 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -49,12 +49,12 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getPrefix()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>> <?php else: ?> <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>" - class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > + class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > <?php foreach ($block->getPrefixOptions() as $_option): ?> <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getPrefix() == $_option): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo __($_option) ?> @@ -75,7 +75,7 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('firstname')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getFirstname()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('firstname')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('firstname')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('firstname')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> </div> </div> <?php if ($middle): ?> @@ -90,7 +90,7 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('middlename')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getMiddlename()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('middlename')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('middlename')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php echo $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('middlename')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php echo $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>> </div> </div> <?php endif; ?> @@ -104,7 +104,7 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('lastname')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getLastname()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('lastname')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('lastname')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('lastname')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> </div> </div> <?php if ($suffix): ?> @@ -119,12 +119,12 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getSuffix()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php else: ?> <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>" - class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> + class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php foreach ($block->getSuffixOptions() as $_option): ?> <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getSuffix() == $_option): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo __($_option) ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml index 4d2b2a411d9..b0ae05d3886 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml @@ -11,6 +11,6 @@ <div class="field taxvat<?php if ($block->isRequired()) echo ' required'; ?>"> <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> <div class="control"> - <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php /* @escapeNotVerified */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> </div> </div> -- GitLab From 3e12751b56826f3f2a1984ba6a88bfb93e0654a7 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Wed, 3 Aug 2016 15:28:43 -0500 Subject: [PATCH 130/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module - Escaped all non-translation instances and removed annotation. - Removed unused templates. --- .../adminhtml/templates/browser/content.phtml | 2 +- .../templates/browser/content/files.phtml | 10 +++++----- .../templates/browser/content/uploader.phtml | 10 +++++----- .../Cms/view/frontend/templates/content.phtml | 10 ---------- .../Cms/view/frontend/templates/meta.phtml | 15 --------------- .../templates/widget/static_block/default.phtml | 2 +- 6 files changed, 12 insertions(+), 37 deletions(-) delete mode 100644 app/code/Magento/Cms/view/frontend/templates/content.phtml delete mode 100644 app/code/Magento/Cms/view/frontend/templates/meta.phtml diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content.phtml index 70a9239af58..703eea1f56a 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content.phtml @@ -17,7 +17,7 @@ <div class="insert-actions"> <?php echo $block->getButtonsHtml() ?> </div> - <div class="title"><?php /* @escapeNotVerified */ echo $block->getHeaderText() ?></div> + <div class="title"><?php echo $block->escapeHtml($block->getHeaderText()) ?></div> </div> </div> <div id="error-message" data-action="show-error"></div> diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml index d86b39547a0..a6185c45418 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/files.phtml @@ -14,16 +14,16 @@ $_height = $block->getImagesHeight(); ?> <?php if ($block->getFilesCount() > 0): ?> <?php foreach ($block->getFiles() as $file): ?> - <div data-row="file" class="filecnt" id="<?php /* @escapeNotVerified */ echo $block->getFileId($file) ?>"> - <p class="nm" style="height:<?php /* @escapeNotVerified */ echo $_height ?>px;width:<?php /* @escapeNotVerified */ echo $_width ?>px;"> + <div data-row="file" class="filecnt" id="<?php echo $block->escapeHtmlAttr($block->getFileId($file)) ?>"> + <p class="nm" style="height:<?php echo $block->escapeHtmlAttr($_height) ?>px;width:<?php echo $block->escapeHtmlAttr($_width) ?>px;"> <?php if ($block->getFileThumbUrl($file)):?> - <img src="<?php /* @escapeNotVerified */ echo $block->getFileThumbUrl($file) ?>" alt="<?php /* @escapeNotVerified */ echo $block->getFileName($file) ?>"/> + <img src="<?php echo $block->escapeHtmlAttr($block->getFileThumbUrl($file)) ?>" alt="<?php echo $block->escapeHtmlAttr($block->getFileName($file)) ?>"/> <?php endif; ?> </p> <?php if ($block->getFileWidth($file)): ?> - <small><?php /* @escapeNotVerified */ echo $block->getFileWidth($file) ?>x<?php /* @escapeNotVerified */ echo $block->getFileHeight($file) ?> <?php /* @escapeNotVerified */ echo __('px.') ?></small><br/> + <small><?php echo $block->escapeHtml($block->getFileWidth($file)) ?>x<?php echo $block->escapeHtml($block->getFileHeight($file)) ?> <?php /* @escapeNotVerified */ echo __('px.') ?></small><br/> <?php endif; ?> - <small><?php /* @escapeNotVerified */ echo $block->getFileShortName($file); ?></small> + <small><?php echo $block->escapeHtml($block->getFileShortName($file)); ?></small> </div> <?php endforeach; ?> <?php else: ?> 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 24482f1fb42..ced0a905412 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 @@ -12,7 +12,7 @@ <div id="<?php echo $block->getHtmlId() ?>" class="uploader"> <span class="fileinput-button form-buttons"> <span><?php /* @escapeNotVerified */ echo __('Browse Files...') ?></span> - <input class="fileupload" type="file" name="<?php /* @escapeNotVerified */ echo $block->getConfig()->getFileField() ?>" data-url="<?php /* @escapeNotVerified */ echo $block->getConfig()->getUrl() ?>" multiple> + <input class="fileupload" type="file" name="<?php echo $block->escapeHtmlAttr($block->getConfig()->getFileField()) ?>" data-url="<?php echo $block->escapeUrl($block->getConfig()->getUrl()) ?>" multiple> </span> <div class="clear"></div> <script type="text/x-magento-template" id="<?php echo $block->getHtmlId() ?>-template"> @@ -39,7 +39,7 @@ require([ }, sequentialUploads: true, acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - maxFileSize: <?php /* @escapeNotVerified */ echo $block->getFileSizeService()->getMaxFileSize() ?> , + maxFileSize: <?php echo $block->escapeJs($block->getFileSizeService()->getMaxFileSize()) ?> , add: function (e, data) { var progressTmpl = mageTemplate('#<?php echo $block->getHtmlId(); ?>-template'), fileSize, @@ -97,11 +97,11 @@ require([ process: [{ action: 'load', fileTypes: /^image\/(gif|jpeg|png)$/, - maxFileSize: <?php /* @escapeNotVerified */ echo $block->getFileSizeService()->getMaxFileSize() ?> * 10 + maxFileSize: <?php echo (int) $block->getFileSizeService()->getMaxFileSize() ?> * 10 }, { action: 'resize', - maxWidth: <?php /* @escapeNotVerified */ echo \Magento\Framework\File\Uploader::MAX_IMAGE_WIDTH ?> , - maxHeight: <?php /* @escapeNotVerified */ echo \Magento\Framework\File\Uploader::MAX_IMAGE_HEIGHT ?> + maxWidth: <?php echo (float) \Magento\Framework\File\Uploader::MAX_IMAGE_WIDTH ?> , + maxHeight: <?php echo (float) \Magento\Framework\File\Uploader::MAX_IMAGE_HEIGHT ?> }, { action: 'save' }] diff --git a/app/code/Magento/Cms/view/frontend/templates/content.phtml b/app/code/Magento/Cms/view/frontend/templates/content.phtml deleted file mode 100644 index 3705cc6dce8..00000000000 --- a/app/code/Magento/Cms/view/frontend/templates/content.phtml +++ /dev/null @@ -1,10 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -?> -<?php /* @escapeNotVerified */ echo $pageData->getPageContent(); ?> diff --git a/app/code/Magento/Cms/view/frontend/templates/meta.phtml b/app/code/Magento/Cms/view/frontend/templates/meta.phtml deleted file mode 100644 index 22e81db7c14..00000000000 --- a/app/code/Magento/Cms/view/frontend/templates/meta.phtml +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -?> -<?php if ($pageData->getPageMetaKeywords()): ?> -<meta name="keywords" content="<?php /* @escapeNotVerified */ echo $pageData->getPageMetaKeywords() ?>"/> -<?php endif; ?> -<?php if ($pageData->getPageMetaDescription()): ?> -<meta name="description" content="<?php /* @escapeNotVerified */ echo $pageData->getPageMetaDescription() ?>"/> -<?php endif; ?> diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml index 110e99da1b0..53c74826a32 100644 --- a/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml @@ -5,5 +5,5 @@ */ ?> <div class="widget block block-static-block"> - <?php /* @escapeNotVerified */ echo $block->getText(); ?> + <?php /* @noEscape */ echo $block->getText(); ?> </div> -- GitLab From f7332364f85e6b9ee83ee9ce52209aa5df757225 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 3 Aug 2016 15:58:38 -0500 Subject: [PATCH 131/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- .../Review/view/frontend/templates/customer/view.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml index 20172e4b546..06c2f591661 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml @@ -39,9 +39,9 @@ $product = $block->getProductData(); <?php $rating = ceil($_rating->getPercent()) ?> <div class="rating-summary item"> <span class="rating-label"><span><?php echo $block->escapeHtml($_rating->getRatingCode()) ?></span></span> - <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> - <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"> - <span><?php echo $block->escapeHtml($rating); ?>%</span> + <div class="rating-result" title="<?php /* noEscape */ echo $rating; ?>%"> + <span style="width:<?php /* noEscape */ echo $rating; ?>%"> + <span><?php /* noEscape */ echo $rating; ?>%</span> </span> </div> </div> -- GitLab From 0f571dc68f0a3d9a24ebe24f09bde7164658dc2c Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Wed, 3 Aug 2016 17:01:27 -0500 Subject: [PATCH 132/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module - Escaped all non-translation instances and removed all annotations. --- .../catalog/category/widget/tree.phtml | 28 ++++---- .../templates/instance/edit/layout.phtml | 72 +++++++++---------- 2 files changed, 50 insertions(+), 50 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml index ad7559e3755..32c7486d867 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -9,16 +9,16 @@ ?> <?php $_divId = 'tree' . $block->getId() ?> -<div id="<?php /* @escapeNotVerified */ echo $_divId ?>" class="tree"></div> +<div id="<?php echo $block->escapeHtmlAttr($_divId) ?>" class="tree"></div> <script id="ie-deferred-loader" defer="defer" src="//:"></script> <script> require(['jquery', "prototype", "extjs/ext-tree-checkbox"], function(jQuery){ -var tree<?php /* @escapeNotVerified */ echo $block->getId() ?>; +var tree<?php echo $block->escapeJs($block->getId()) ?>; -var useMassaction = <?php /* @escapeNotVerified */ echo $block->getUseMassaction() ? 1 : 0; ?>; +var useMassaction = <?php /* @noEscape */ echo $block->getUseMassaction() ? 1 : 0; ?>; -var isAnchorOnly = <?php /* @escapeNotVerified */ echo $block->getIsAnchorOnly() ? 1 : 0; ?>; +var isAnchorOnly = <?php /* @noEscape */ echo $block->getIsAnchorOnly() ? 1 : 0; ?>; Ext.tree.TreePanel.Enhanced = function(el, config) { @@ -43,7 +43,7 @@ Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { if (firstLoad) { <?php if ($block->getNodeClickListener()): ?> - this.addListener('click', <?php /* @escapeNotVerified */ echo $block->getNodeClickListener() ?>.createDelegate(this)); + this.addListener('click', <?php echo $block->escapeJs($block->getNodeClickListener()) ?>.createDelegate(this)); <?php endif; ?> } @@ -56,10 +56,10 @@ Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { jQuery(function() { - var emptyNodeAdded = <?php /* @escapeNotVerified */ echo($block->getWithEmptyNode() ? 'false' : 'true') ?>; + var emptyNodeAdded = <?php /* @noEscape */ echo($block->getWithEmptyNode() ? 'false' : 'true') ?>; var categoryLoader = new Ext.tree.TreeLoader({ - dataUrl: '<?php /* @escapeNotVerified */ echo $block->getLoadTreeUrl() ?>' + dataUrl: '<?php echo $block->escapeUrl($block->getLoadTreeUrl()) ?>' }); categoryLoader.buildCategoryTree = function(parent, config) @@ -149,25 +149,25 @@ jQuery(function() }; categoryLoader.on("beforeload", function(treeLoader, node) { - $('<?php /* @escapeNotVerified */ echo $_divId; ?>').fire('category:beforeLoad', {treeLoader:treeLoader}); + $('<?php echo $block->escapeJs($_divId); ?>').fire('category:beforeLoad', {treeLoader:treeLoader}); treeLoader.baseParams.id = node.attributes.id; }); - tree<?php /* @escapeNotVerified */ echo $block->getId() ?> = new Ext.tree.TreePanel.Enhanced('<?php /* @escapeNotVerified */ echo $_divId ?>', { + tree<?php echo $block->escapeJs($block->getId()) ?> = new Ext.tree.TreePanel.Enhanced('<?php echo $block->escapeJs($_divId) ?>', { animate: false, loader: categoryLoader, enableDD: false, containerScroll: true, - rootVisible: '<?php /* @escapeNotVerified */ echo $block->getRoot()->getIsVisible() ?>', + rootVisible: '<?php echo $block->escapeJs($block->getRoot()->getIsVisible()) ?>', useAjax: true, currentNodeId: <?php echo (int) $block->getCategoryId() ?>, addNodeTo: false }); if (useMassaction) { - tree<?php /* @escapeNotVerified */ echo $block->getId() ?>.on('check', function(node) { - $('<?php /* @escapeNotVerified */ echo $_divId; ?>').fire('node:changed', {node:node}); - }, tree<?php /* @escapeNotVerified */ echo $block->getId() ?>); + tree<?php echo $block->escapeJs($block->getId()) ?>.on('check', function(node) { + $('<?php echo $block->escapeJs($_divId); ?>').fire('node:changed', {node:node}); + }, tree<?php echo $block->escapeJs($block->getId()) ?>); } // set the root node @@ -179,7 +179,7 @@ jQuery(function() category_id: <?php echo (int) $block->getCategoryId() ?> }; - tree<?php /* @escapeNotVerified */ echo $block->getId() ?>.loadTree({parameters:parameters, data:<?php /* @escapeNotVerified */ echo $block->getTreeJson() ?>},true); + tree<?php echo $block->escapeJs($block->getId()) ?>.loadTree({parameters:parameters, data:<?php /* @noEscape */ echo $block->getTreeJson() ?>},true); }); diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index 418e3975d2a..50e2b4faf96 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -32,15 +32,15 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<label for="widget_instance[<%- data.id %>][page_group]">Display on <span class="required">*</span></label>'+ '<?php echo $block->getDisplayOnSelectHtml(); ?>'+ '<div class="actions">'+ - <?php /* @escapeNotVerified */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getRemoveLayoutButtonHtml()) ?> + + <?php /* @noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getRemoveLayoutButtonHtml()) ?> + '</div>'+ '</div>'+ '<div class="fieldset-wrapper-content">'+ <?php foreach ($block->getDisplayOnContainers() as $container): ?> - '<div class="no-display <?php /* @escapeNotVerified */ echo $container['code'] ?> group_container" id="<?php /* @escapeNotVerified */ echo $container['name'] ?>_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>]" />'+ - '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][page_id]" value="<%- data.page_id %>" />'+ - '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][layout_handle]" value="<?php /* @escapeNotVerified */ echo $container['layout_handle'] ?>" />'+ + '<div class="no-display <?php echo $block->escapeJs($container['code']) ?> group_container" id="<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>">'+ + '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php echo $block->escapeHtml($container['name']) ?>]" />'+ + '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][page_id]" value="<%- data.page_id %>" />'+ + '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][layout_handle]" value="<?php echo $block->escapeJs($container['layout_handle']) ?>" />'+ '<table class="data-table">'+ '<col width="200" />'+ '<thead>'+ @@ -53,10 +53,10 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<tbody>'+ '<tr>'+ '<td>'+ - '<input disabled="disabled" type="radio" class="radio for_all" id="all_<?php /* @escapeNotVerified */ echo $container['name'] ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][for]" value="all" onclick="WidgetInstance.togglePageGroupChooser(this)" checked="checked" /> '+ - '<label for="all_<?php /* @escapeNotVerified */ echo $container['name'] ?>_<%- data.id %>"><?php echo $block->escapeJs(__('All')) ?></label><br />'+ - '<input disabled="disabled" type="radio" class="radio for_specific" id="specific_<?php /* @escapeNotVerified */ echo $container['name'] ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][for]" value="specific" onclick="WidgetInstance.togglePageGroupChooser(this)" /> '+ - '<label for="specific_<?php /* @escapeNotVerified */ echo $container['name'] ?>_<%- data.id %>"><?php echo $block->escapeJs(__('Specific %1', $container['label'])) ?></label>'+ + '<input disabled="disabled" type="radio" class="radio for_all" id="all_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][for]" value="all" onclick="WidgetInstance.togglePageGroupChooser(this)" checked="checked" /> '+ + '<label for="all_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>"><?php echo $block->escapeJs(__('All')) ?></label><br />'+ + '<input disabled="disabled" type="radio" class="radio for_specific" id="specific_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][for]" value="specific" onclick="WidgetInstance.togglePageGroupChooser(this)" /> '+ + '<label for="specific_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>"><?php echo $block->escapeJs(__('Specific %1', $container['label'])) ?></label>'+ '</td>'+ '<td>'+ '<div class="block_reference_container">'+ @@ -71,16 +71,16 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</tr>'+ '</tbody>'+ '</table>'+ - '<div class="no-display chooser_container" id="<?php /* @escapeNotVerified */ echo $container['name'] ?>_ids_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="is_anchor_only" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][is_anchor_only]" value="<?php /* @escapeNotVerified */ echo $container['is_anchor_only'] ?>" />'+ - '<input disabled="disabled" type="hidden" class="product_type_id" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][product_type_id]" value="<?php /* @escapeNotVerified */ echo $container['product_type_id'] ?>" />'+ + '<div class="no-display chooser_container" id="<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>">'+ + '<input disabled="disabled" type="hidden" class="is_anchor_only" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][is_anchor_only]" value="<?php echo $block->escapeJs($container['is_anchor_only']) ?>" />'+ + '<input disabled="disabled" type="hidden" class="product_type_id" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][product_type_id]" value="<?php echo $block->escapeJs($container['product_type_id']) ?>" />'+ '<p>' + - '<input disabled="disabled" type="text" class="input-text entities" name="widget_instance[<%- data.id %>][<?php /* @escapeNotVerified */ echo $container['name'] ?>][entities]" value="<%- data.<?php /* @escapeNotVerified */ echo $container['name'] ?>_entities %>" readonly="readonly" /> ' + - '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php /* @escapeNotVerified */ echo $container['code'] ?>\', \'<?php /* @escapeNotVerified */ echo $container['name'] ?>_ids_<%- data.id %>\')" title="<?php /* @escapeNotVerified */ echo $block->escapeJs(__('Open Chooser')) ?>">' + - '<img src="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/rule_chooser_trigger.gif') ?>" alt="<?php /* @escapeNotVerified */ echo $block->escapeJs(__('Open Chooser')); ?>" />' + + '<input disabled="disabled" type="text" class="input-text entities" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][entities]" value="<%- data.<?php echo $block->escapeJs($container['name']) ?>_entities %>" readonly="readonly" /> ' + + '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php echo $block->escapeJs($container['code']) ?>\', \'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Open Chooser')) ?>">' + + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_chooser_trigger.gif')) ?>" alt="<?php echo $block->escapeJs(__('Open Chooser')); ?>" />' + '</a> ' + - '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php /* @escapeNotVerified */ echo $container['name'] ?>_ids_<%- data.id %>\')" title="<?php /* @escapeNotVerified */ echo $block->escapeJs(__('Apply')); ?>">' + - '<img src="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/rule_component_apply.gif') ?>" alt="<?php /* @escapeNotVerified */ echo $block->escapeJs(__('Apply')); ?>" />' + + '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeHtmlAttr($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Apply')); ?>">' + + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>" alt="<?php echo $block->escapeJs(__('Apply')); ?>" />' + '</a>' + '</p>'+ '<div class="chooser"></div>'+ @@ -96,8 +96,8 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '<th> </th>'+ '</tr>'+ '</thead>'+ @@ -126,14 +126,14 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php /* @escapeNotVerified */ echo $block->getLayoutsChooser() ?></td>'+ + '<td><?php echo $block->escapeHtml($block->getLayoutsChooser()) ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ @@ -157,14 +157,14 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php /* @escapeNotVerified */ echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php /* @escapeNotVerified */ echo $block->getPageLayoutsPageChooser() ?></td>'+ + '<td><?php echo $block->escapeJs($block->getPageLayoutsPageChooser()) ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ @@ -245,10 +245,10 @@ var WidgetInstance = { } forElm = pageGroup.down('input.for_'+data.for_value); if (forElm) { - /** - * IE browsers fix: remove default checked attribute in radio form element - * to check others radio form elements in future - */ + /* + * IE browsers fix: remove default checked attribute in radio form element + * to check others radio form elements in future + */ pageGroup.down('input.for_all').defaultChecked = false; forElm.defaultChecked = true; forElm.checked = true; @@ -332,10 +332,10 @@ var WidgetInstance = { additional = {}; } if (type == 'categories') { - additional.url = '<?php /* @escapeNotVerified */ echo $block->getCategoriesChooserUrl() ?>'; + additional.url = '<?php echo $block->escapeUrl($block->getCategoriesChooserUrl()) ?>'; additional.post_parameters = $H({'is_anchor_only':$(chooser).down('input.is_anchor_only').value}); } else if (type == 'products') { - additional.url = '<?php /* @escapeNotVerified */ echo $block->getProductsChooserUrl() ?>'; + additional.url = '<?php echo $block->escapeUrl($block->getProductsChooserUrl()) ?>'; additional.post_parameters = $H({'product_type_id':$(chooser).down('input.product_type_id').value}); } if (chooser && additional) { @@ -441,13 +441,13 @@ var WidgetInstance = { selected = ''; parameters = {}; if (type == 'block_reference') { - url = '<?php /* @escapeNotVerified */ echo $block->getBlockChooserUrl() ?>'; + url = '<?php echo $block->escapeUrl($block->getBlockChooserUrl()) ?>'; if (additional.selectedBlock) { selected = additional.selectedBlock; } parameters.layout = value; } else if (type == 'block_template') { - url = '<?php /* @escapeNotVerified */ echo $block->getTemplateChooserUrl() ?>'; + url = '<?php echo $block->escapeUrl($block->getTemplateChooserUrl()) ?>'; if (additional.selectedTemplate) { selected = additional.selectedTemplate; } @@ -485,7 +485,7 @@ window.WidgetInstance = WidgetInstance; jQuery(function(){ <?php foreach ($block->getPageGroups() as $pageGroup): ?> - WidgetInstance.addPageGroup(<?php /* @escapeNotVerified */ echo Zend_Json::encode($pageGroup) ?>); + WidgetInstance.addPageGroup(<?php /* @noEscape */ echo Zend_Json::encode($pageGroup) ?>); <?php endforeach; ?> Event.observe(document, 'product:changed', function(event){ WidgetInstance.checkProduct(event); -- GitLab From 848a5a5c2b30a12e96b80d4ad2dfa682a75dbb0a Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 3 Aug 2016 17:18:29 -0500 Subject: [PATCH 133/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../adminhtml/templates/customer/edit/tab/wishlist.phtml | 5 +---- .../Wishlist/view/frontend/templates/button/share.phtml | 3 +-- .../Wishlist/view/frontend/templates/button/tocart.phtml | 3 +-- .../Wishlist/view/frontend/templates/button/update.phtml | 3 +-- .../cart/item/renderer/actions/move_to_wishlist.phtml | 3 +-- .../templates/catalog/product/list/addto/wishlist.phtml | 2 +- .../templates/catalog/product/view/addto/wishlist.phtml | 3 +-- .../Wishlist/view/frontend/templates/email/items.phtml | 3 +-- .../view/frontend/templates/item/column/actions.phtml | 5 ++--- .../Wishlist/view/frontend/templates/item/column/cart.phtml | 3 +-- .../view/frontend/templates/item/column/comment.phtml | 1 - .../Wishlist/view/frontend/templates/item/column/edit.phtml | 3 +-- .../Wishlist/view/frontend/templates/item/column/image.phtml | 3 +-- .../Wishlist/view/frontend/templates/item/column/name.phtml | 5 ++--- .../Wishlist/view/frontend/templates/item/column/price.phtml | 3 +-- .../view/frontend/templates/item/column/remove.phtml | 2 +- .../view/frontend/templates/item/configure/addto.phtml | 3 +-- .../frontend/templates/item/configure/addto/wishlist.phtml | 3 +-- .../Magento/Wishlist/view/frontend/templates/item/list.phtml | 3 +-- app/code/Magento/Wishlist/view/frontend/templates/link.phtml | 3 +-- .../templates/messages/addProductSuccessMessage.phtml | 3 +-- .../Wishlist/view/frontend/templates/options_list.phtml | 3 +-- .../Magento/Wishlist/view/frontend/templates/rss/email.phtml | 2 +- .../Wishlist/view/frontend/templates/rss/wishlist.phtml | 3 +-- .../Magento/Wishlist/view/frontend/templates/shared.phtml | 3 +-- .../Magento/Wishlist/view/frontend/templates/sharing.phtml | 3 +-- .../Magento/Wishlist/view/frontend/templates/sidebar.phtml | 3 +-- app/code/Magento/Wishlist/view/frontend/templates/view.phtml | 3 +-- 28 files changed, 29 insertions(+), 56 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index af308a9dbf7..63377fcbbbe 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -6,10 +6,7 @@ // @codingStandardsIgnoreFile -/** - * @var $block \Magento\Framework\View\Element\Template - */ - +/** @var \Magento\Framework\View\Element\Template $block */ ?> <script> require([ diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml index e516d39d11c..51dc0d7b3db 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ - +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Button $block */ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->getShared() < $block->getConfig()->getSharingEmailLimit()): ?> <button type="submit" name="save_and_share" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action share"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml index 1fc4b5fe4f8..3f2984eac3f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ - +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Button $block */ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->isSalable()): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml index 8ea857b1195..dfb24bde08b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Button */ - +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Button $block */ ?> <?php if ($block->getWishlist()->getItemsCount()): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml index 01302361efa..26d35fd8cfc 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Cart\Item\Renderer\Actions\MoveToWishlist */ - +/** @var \Magento\Wishlist\Block\Cart\Item\Renderer\Actions\MoveToWishlist $block */ ?> <?php if ($block->isAllowInCart() && $block->isProductVisibleInSiteVisibility()): ?> <a href="#" diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index 292fe608106..4534fdc5653 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -5,8 +5,8 @@ */ // @codingStandardsIgnoreFile -/** @var $block Magento\Wishlist\Block\Catalog\Product\ProductList\Item\AddTo\Wishlist */ +/** @var Magento\Wishlist\Block\Catalog\Product\ProductList\Item\AddTo\Wishlist $block */ ?> <?php if ($block->getWishlistHelper()->isAllow()): ?> <a href="#" diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml index 8f033e64fe6..104d56f72dd 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Catalog\Product\View\AddTo\Wishlist */ - +/** @var \Magento\Wishlist\Block\Catalog\Product\View\AddTo\Wishlist $block */ ?> <?php if ($block->isWishListAllowed()) : ?> <a href="#" diff --git a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml index b573b9126a0..003aa4db62d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Share\Email\Items */ - +/* @var \Magento\Wishlist\Block\Share\Email\Items $block */ ?> <?php $l = $block->getWishlistItemsCount() ?> <div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index e40238035f4..275d123f69d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -6,9 +6,8 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions */ -/* @var $item \Magento\Wishlist\Model\Item */ - +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ +/* @var \Magento\Wishlist\Model\Item $item */ ?> <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> 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 23307b35df2..1c041e67822 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 @@ -6,12 +6,11 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); - ?> <?php foreach ($block->getChildNames() as $childName): ?> <?php /* @noEscape */ echo $block->getLayout()->renderElement($childName, false); ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index a3ef2d53f34..66f56f66a07 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -10,7 +10,6 @@ /* @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); - ?> <div class="field comment-box"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index 0c454e38e6b..d7e523931c0 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -6,12 +6,11 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Edit $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); - ?> <?php if ($product->isVisibleInSiteVisibility()): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml index 19b278185a3..3aa663f30de 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/image.phtml @@ -6,12 +6,11 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Image $block */ /** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); - ?> <a class="product-item-photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtmlAttr($product->getName()) ?>"> <?php echo $block->getImage($product, 'wishlist_thumbnail')->toHtml(); ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml index ddb06755d46..6c8092383fe 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/name.phtml @@ -6,12 +6,11 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Info $block */ -/** @var $item \Magento\Wishlist\Model\Item */ +/** @var \Magento\Wishlist\Model\Item $item */ $item = $block->getItem(); $product = $item->getProduct(); - ?> <strong class="product-item-name"> <a href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtmlAttr($product->getName()) ?>" class="product-item-link"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml index 767ece01986..beb082cc72a 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml @@ -6,9 +6,8 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart $block */ /** @var \Magento\Wishlist\Model\Item $item */ - ?> <?php foreach ($block->getChildNames() as $childName): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index 433440d1611..b358362c111 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove */ +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml index d285d41bdf8..26a28b2c3bd 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Item\configure */ - +/** @var \Magento\Wishlist\Block\Item\configure $block */ ?> <div class="product-addto-links" data-role="add-to-links"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml index 651f6108e45..9d721e9a50c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Item\Configure */ - +/** @var \Magento\Wishlist\Block\Item\Configure $block */ ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml index b5f56833316..9850f8fa7ea 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml @@ -8,9 +8,8 @@ ?> <?php -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist\Items */ +/** @var \Magento\Wishlist\Block\Customer\Wishlist\Items $block */ $columns = $block->getColumns(); - ?> <div class="products-grid wishlist"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/link.phtml b/app/code/Magento/Wishlist/view/frontend/templates/link.phtml index d4867e94404..cc1e69980c2 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/link.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/link.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Link */ - +/* @var \Magento\Wishlist\Block\Link $block */ ?> <li class="link wishlist" data-bind="scope: 'wishlist'"> <a <?php /* @noEscape */ echo $block->getLinkAttributes() ?>><?php echo $block->escapeHtml($block->getLabel()) ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml index 4a06e3489c9..a040c2c8ca7 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml @@ -4,8 +4,7 @@ * See COPYING.txt for license details. */ -/** @var $block \Magento\Framework\View\Element\Template */ - +/** @var \Magento\Framework\View\Element\Template $block */ ?> <?php /* @escapeNotVerified */ echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php /* @escapeNotVerified */ echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index 480266c466d..acd198d0f83 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Customer\Wishlist\Item\Options */ - +/* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Options $block */ ?> <?php $options = $block->getOptionList(); ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml index 54eac70c29b..13685949a29 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/* @var $block \Magento\Wishlist\Block\Rss\EmailLink */ +/* @var \Magento\Wishlist\Block\Rss\EmailLink $block */ ?> <?php if ($block->getLink()): ?> <p style="font-size:12px; line-height:16px; margin:0 0 16px;"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml index 475a1c4c8b6..1e297c4673d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Rss\Link */ - +/** @var \Magento\Wishlist\Block\Rss\Link $block */ ?> <?php if ($block->isRssAllowed() && $block->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?> <a href="<?php echo $block->escapeUrl($block->getLink()); ?>" class="action rss wishlist"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index c8045ccdcf1..201a5ef3722 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Share\Wishlist */ - +/** @var \Magento\Wishlist\Block\Share\Wishlist $block */ ?> <?php if ($block->hasWishlistItems()): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index 5ffe6c892e5..a21811b384f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Sharing */ - +/** @var \Magento\Wishlist\Block\Customer\Sharing $block */ ?> <form class="form wishlist share" action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml index 39cbb16d837..28e339162d5 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Sidebar */ - +/** @var \Magento\Wishlist\Block\Customer\Sidebar $block */ ?> <?php $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml index 03aa0707507..748e1e4386c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml @@ -6,8 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Wishlist\Block\Customer\Wishlist */ - +/** @var \Magento\Wishlist\Block\Customer\Wishlist $block */ ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> -- GitLab From 031f926e347c74cd3821be305da1a9510a6e580c Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 4 Aug 2016 11:41:38 +0300 Subject: [PATCH 134/838] MAGETWO-55267: Modify Update Grid --- .../magento/setup/install-extension-grid.js | 84 +++--------------- setup/pub/magento/setup/main.js | 85 +++++++++++++++++++ .../magento/setup/update-extension-grid.js | 32 ++++++- .../src/Magento/Setup/Model/PackagesData.php | 4 +- .../setup/install-extension-grid.phtml | 26 +++--- .../magento/setup/update-extension-grid.phtml | 45 ++++++++++ 6 files changed, 187 insertions(+), 89 deletions(-) diff --git a/setup/pub/magento/setup/install-extension-grid.js b/setup/pub/magento/setup/install-extension-grid.js index f4ed97baae3..8bbf3883b31 100644 --- a/setup/pub/magento/setup/install-extension-grid.js +++ b/setup/pub/magento/setup/install-extension-grid.js @@ -5,20 +5,17 @@ 'use strict'; angular.module('install-extension-grid', ['ngStorage', 'clickOut']) - .controller('installExtensionGridController', ['$scope', '$http', '$localStorage', 'authService', 'paginationService', - function ($scope, $http, $localStorage, authService, paginationService) { + .controller('installExtensionGridController', ['$scope', '$http', '$localStorage', 'authService', 'paginationService', 'multipleChoiceService', + function ($scope, $http, $localStorage, authService, paginationService, multipleChoiceService) { $http.get('index.php/installExtensionGrid/extensions').success(function(data) { $scope.error = false; $scope.errorMessage = ''; - $scope.selectedExtensions = {}; - $scope.allExtensions = {}; + $scope.multipleChoiceService = multipleChoiceService; + $scope.multipleChoiceService.reset(); angular.forEach(data.extensions, function(value) { - this[value.name] = { - 'name': value.name, - 'version': value.version - }; - }, $scope.allExtensions); + $scope.multipleChoiceService.addExtension(value.name, value.version); + }); $scope.extensions = data.extensions; $scope.total = data.total; $scope.currentPage = 1; @@ -28,31 +25,6 @@ angular.module('install-extension-grid', ['ngStorage', 'clickOut']) paginationService.initWatchers($scope); - $scope.updateSelectedExtensions = function($event, name, version) { - var checkbox = $event.target; - if (checkbox.checked) { - $scope.selectedExtensions[name] = { - 'name': name, - 'version': version - }; - if ($scope.getObjectSize($scope.selectedExtensions) == $scope.getObjectSize($scope.allExtensions)) { - $scope.someExtensionsSelected = false; - $scope.allExtensionsSelected = true; - } else { - $scope.someExtensionsSelected = true; - $scope.allExtensionsSelected = false; - } - } else { - delete $scope.selectedExtensions[name]; - $scope.allExtensionsSelected = false; - if ($scope.getObjectSize($scope.selectedExtensions) > 0) { - $scope.someExtensionsSelected = true; - } else { - $scope.someExtensionsSelected = false; - } - } - }; - $scope.predicate = 'name'; $scope.reverse = false; $scope.order = function(predicate) { @@ -60,58 +32,22 @@ angular.module('install-extension-grid', ['ngStorage', 'clickOut']) $scope.predicate = predicate; }; - $scope.getObjectSize = function(obj) { - var size = 0, key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - ++size; - } - } - return size; - }; - - $scope.isNewExtensionsMenuVisible = false; - $scope.toggleNewExtensionsMenu = function() { - $scope.isNewExtensionsMenuVisible = !$scope.isNewExtensionsMenuVisible; - }; - $scope.hideNewExtensionsMenu = function() { - $scope.isNewExtensionsMenuVisible = false; - }; - $scope.someExtensionsSelected = false; - $scope.allExtensionsSelected = false; - $scope.selectAllExtensions = function() { - $scope.isNewExtensionsMenuVisible = false; - $scope.someExtensionsSelected = false; - $scope.allExtensionsSelected = true; - $scope.selectedExtensions = angular.copy($scope.allExtensions); - }; - $scope.deselectAllExtensions = function() { - $scope.isNewExtensionsMenuVisible = false; - $scope.someExtensionsSelected = false; - $scope.allExtensionsSelected = false; - $scope.selectedExtensions = {}; - }; - $scope.isHiddenSpinner = true; $scope.installAll = function() { $scope.isHiddenSpinner = false; authService.checkAuth({ success: function(response) { $scope.isHiddenSpinner = true; - if ($scope.getObjectSize($scope.selectedExtensions) > 0) { - $scope.error = false; - $scope.errorMessage = ''; - $localStorage.packages = $scope.selectedExtensions; - } else { - $scope.error = true; - $scope.errorMessage = 'Please select at least one extension'; - } + var result = $scope.multipleChoiceService.checkSelectedExtensions(); + $scope.error = result.error; + $scope.errorMessage = result.errorMessage; if (!$scope.error) { $scope.nextState(); } }, fail: function(response) { + $scope.isHiddenSpinner = true; authService.openAuthDialog($scope); }, error: function() { diff --git a/setup/pub/magento/setup/main.js b/setup/pub/magento/setup/main.js index 37af464bbb3..f9051ee27d0 100644 --- a/setup/pub/magento/setup/main.js +++ b/setup/pub/magento/setup/main.js @@ -273,6 +273,91 @@ main.controller('navigationController', }; } ]) +.service('multipleChoiceService', ['$localStorage', + function ($localStorage) { + return { + selectedExtensions: {}, + allExtensions: {}, + someExtensionsSelected: false, + allExtensionsSelected: false, + isNewExtensionsMenuVisible: false, + + addExtension: function (name, version) { + this.allExtensions[name] = { + 'name': name, + 'version': version + }; + }, + reset: function () { + this.allExtensions = {}; + this.selectedExtensions = {}; + this.someExtensionsSelected = false; + this.allExtensionsSelected = false; + this.isNewExtensionsMenuVisible = false; + }, + updateSelectedExtensions: function ($event, name, version) { + var checkbox = $event.target; + if (checkbox.checked) { + this.selectedExtensions[name] = { + 'name': name, + 'version': version + }; + if (this._getObjectSize(this.selectedExtensions) == this._getObjectSize(this.allExtensions)) { + this.someExtensionsSelected = false; + this.allExtensionsSelected = true; + } else { + this.someExtensionsSelected = true; + this.allExtensionsSelected = false; + } + } else { + delete this.selectedExtensions[name]; + this.allExtensionsSelected = false; + this.someExtensionsSelected = (this._getObjectSize(this.selectedExtensions) > 0); + } + }, + toggleNewExtensionsMenu: function() { + this.isNewExtensionsMenuVisible = !this.isNewExtensionsMenuVisible; + }, + hideNewExtensionsMenu: function() { + this.isNewExtensionsMenuVisible = false; + }, + selectAllExtensions: function() { + this.isNewExtensionsMenuVisible = false; + this.someExtensionsSelected = false; + this.allExtensionsSelected = true; + this.selectedExtensions = angular.copy(this.allExtensions); + }, + deselectAllExtensions: function() { + this.isNewExtensionsMenuVisible = false; + this.someExtensionsSelected = false; + this.allExtensionsSelected = false; + this.selectedExtensions = {}; + }, + checkSelectedExtensions: function() { + var result = {error: false, errorMessage: ''}; + if (this._getObjectSize(this.selectedExtensions) > 0) { + result.error = false; + result.errorMessage = ''; + $localStorage.packages = this.selectedExtensions; + } else { + result.error = true; + result.errorMessage = 'Please select at least one extension'; + } + + return result; + }, + _getObjectSize: function (obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + ++size; + } + } + return size; + } + }; + } +]) .filter('startFrom', function () { return function (input, start) { if (input !== undefined && start !== 'NaN') { diff --git a/setup/pub/magento/setup/update-extension-grid.js b/setup/pub/magento/setup/update-extension-grid.js index f28e0aa385a..80dd0e9cb7c 100644 --- a/setup/pub/magento/setup/update-extension-grid.js +++ b/setup/pub/magento/setup/update-extension-grid.js @@ -5,15 +5,18 @@ 'use strict'; angular.module('update-extension-grid', ['ngStorage', 'clickOut']) - .controller('updateExtensionGridController', ['$scope', '$http', '$localStorage', 'titleService', 'paginationService', - function ($scope, $http, $localStorage, titleService, paginationService) { + .controller('updateExtensionGridController', ['$scope', '$http', '$localStorage', 'titleService', 'authService', 'paginationService', 'multipleChoiceService', + function ($scope, $http, $localStorage, titleService, authService, paginationService, multipleChoiceService) { $scope.isHiddenSpinner = false; $http.get('index.php/updateExtensionGrid/extensions').success(function(data) { $scope.error = false; $scope.errorMessage = ''; + $scope.multipleChoiceService = multipleChoiceService; + $scope.multipleChoiceService.reset(); angular.forEach(data.extensions, function(extension) { extension.updateVersion = extension.latestVersion; + $scope.multipleChoiceService.addExtension(extension.name, extension.latestVersion); }); $scope.extensions = data.extensions; $scope.total = data.total; @@ -42,5 +45,30 @@ angular.module('update-extension-grid', ['ngStorage', 'clickOut']) titleService.setTitle('update', extension.name); $scope.nextState(); }; + $scope.isHiddenSpinner = true; + $scope.updateAll = function() { + $scope.isHiddenSpinner = false; + authService.checkAuth({ + success: function(response) { + $scope.isHiddenSpinner = true; + var result = $scope.multipleChoiceService.checkSelectedExtensions(); + $scope.error = result.error; + $scope.errorMessage = result.errorMessage; + + if (!$scope.error) { + $scope.nextState(); + } + }, + fail: function(response) { + $scope.isHiddenSpinner = true; + authService.openAuthDialog($scope); + }, + error: function() { + $scope.isHiddenSpinner = true; + $scope.error = true; + $scope.errorMessage = 'Internal server error'; + } + }); + }; } ]); diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index 0138212ef39..ebb4f910469 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -273,9 +273,9 @@ class PackagesData ksort($package); $packageValues = array_values($package); if ($this->isNewUserPackage($packageValues[0], $packageNames)) { - $versions = array_reverse(array_keys($package)); + uksort($package, 'version_compare'); $installPackage = $packageValues[0]; - $installPackage['versions'] = $versions; + $installPackage['versions'] = array_reverse(array_keys($package)); $installPackage['name'] = $packageName; $installPackage['vendor'] = explode('/', $packageName)[0]; $installPackages[$packageName] = $installPackage; diff --git a/setup/view/magento/setup/install-extension-grid.phtml b/setup/view/magento/setup/install-extension-grid.phtml index 04dc3499371..ec8ffabb449 100644 --- a/setup/view/magento/setup/install-extension-grid.phtml +++ b/setup/view/magento/setup/install-extension-grid.phtml @@ -33,28 +33,31 @@ <tr> <th class="data-grid-multicheck-cell"> <div class="action-multicheck-wrap" - ng-class="{'_active':isNewExtensionsMenuVisible}" - click-out="hideNewExtensionsMenu()" + ng-class="{'_active':multipleChoiceService.isNewExtensionsMenuVisible}" + click-out="multipleChoiceService.hideNewExtensionsMenu()" > <input type="checkbox" style="visibility: hidden;" class="admin__control-checkbox" - ng-class="{'_indeterminate':someExtensionsSelected}" - ng-checked="allExtensionsSelected" + ng-class="{'_indeterminate':multipleChoiceService.someExtensionsSelected}" + ng-checked="multipleChoiceService.allExtensionsSelected" > <label></label> <button class="action-multicheck-toggle" - ng-class="{'_active':isNewExtensionsMenuVisible}" - ng-click="toggleNewExtensionsMenu()" + ng-class="{'_active':multipleChoiceService.isNewExtensionsMenuVisible}" + ng-click="multipleChoiceService.toggleNewExtensionsMenu()" > <span>Options</span> </button> <ul class="action-menu"> - <li ng-show="!allExtensionsSelected" ng-click="selectAllExtensions()"> + <li ng-show="!multipleChoiceService.allExtensionsSelected" + ng-click="multipleChoiceService.selectAllExtensions()" + > <span class="action-menu-item">Select all</span> </li> - <li ng-show="allExtensionsSelected || someExtensionsSelected" - ng-click="deselectAllExtensions()"> + <li ng-show="multipleChoiceService.allExtensionsSelected + || multipleChoiceService.someExtensionsSelected" + ng-click="multipleChoiceService.deselectAllExtensions()"> <span class="action-menu-item">Deselect all</span> </li> </ul> @@ -89,8 +92,9 @@ <label class="data-grid-checkbox-cell-inner"> <input type="checkbox" class="admin__control-checkbox" - ng-checked="selectedExtensions.hasOwnProperty(extension.name)" - ng-click="updateSelectedExtensions($event, extension.name, extension.version)" + ng-checked="multipleChoiceService.selectedExtensions.hasOwnProperty(extension.name)" + ng-click="multipleChoiceService.updateSelectedExtensions($event, extension.name, + extension.version)" > <label></label> </label> diff --git a/setup/view/magento/setup/update-extension-grid.phtml b/setup/view/magento/setup/update-extension-grid.phtml index 2c8625a82ed..c1f1a40f17b 100644 --- a/setup/view/magento/setup/update-extension-grid.phtml +++ b/setup/view/magento/setup/update-extension-grid.phtml @@ -17,6 +17,7 @@ <div class="admin__data-grid-header"> <div class="admin__data-grid-header-row row row-gutter"> <div class="col-xs-3"> + <button type="button" class="btn" ng-click="updateAll()">Update</button> <div class="admin__control-support-text"> <span>{{total}}</span> products </div> @@ -30,6 +31,39 @@ <table class="data-grid"> <thead data-part="head"> <tr> + <th class="data-grid-multicheck-cell"> + <div class="action-multicheck-wrap" + ng-class="{'_active':multipleChoiceService.isNewExtensionsMenuVisible}" + click-out="multipleChoiceService.hideNewExtensionsMenu()" + > + <input type="checkbox" + style="visibility: hidden;" + class="admin__control-checkbox" + ng-class="{'_indeterminate':multipleChoiceService.someExtensionsSelected}" + ng-checked="multipleChoiceService.allExtensionsSelected" + > + <label></label> + <button class="action-multicheck-toggle" + ng-class="{'_active':multipleChoiceService.isNewExtensionsMenuVisible}" + ng-click="multipleChoiceService.toggleNewExtensionsMenu()" + > + <span>Options</span> + </button> + <ul class="action-menu"> + <li ng-show="!multipleChoiceService.allExtensionsSelected" + ng-click="multipleChoiceService.selectAllExtensions()" + > + <span class="action-menu-item">Select all</span> + </li> + <li ng-show="multipleChoiceService.allExtensionsSelected + || multipleChoiceService.someExtensionsSelected" + ng-click="multipleChoiceService.deselectAllExtensions()" + > + <span class="action-menu-item">Deselect all</span> + </li> + </ul> + </div> + </th> <th ng-click="order('name')" ng-class="{'_ascend' : predicate === 'name' && !reverse,'_descend' : predicate === 'name' && reverse}" class="data-grid-th _sortable"> <span>Product Name</span> @@ -58,6 +92,17 @@ <tr ng-repeat="extension in extensions | orderBy:predicate:reverse | startFrom:(currentPage - 1) * rowLimit | limitTo:rowLimit" > + <td class="data-grid-checkbox-cell"> + <label class="data-grid-checkbox-cell-inner"> + <input type="checkbox" + class="admin__control-checkbox" + ng-checked="multipleChoiceService.selectedExtensions.hasOwnProperty(extension.name)" + ng-click="multipleChoiceService.updateSelectedExtensions($event, extension.name, + extension.latestVersion)" + > + <label></label> + </label> + </td> <td> <span class="data-grid-data">{{extension.name}}</span> </td> -- GitLab From 5734c54e82f2d82e7c5b81cfc5c57c03c49ea211 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 4 Aug 2016 11:44:32 +0300 Subject: [PATCH 135/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - code style fix --- app/code/Magento/Ui/view/base/web/js/form/element/abstract.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 40152bd9209..3a4b7439bcc 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -79,6 +79,7 @@ define([ * @returns {Boolean} */ isInvalid: function () { + return this.error() && this.error().length ? this : false; }, -- GitLab From dcf7f3e03f3b4ac16e1a8a61686762f79f6e126f Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 4 Aug 2016 11:50:51 +0300 Subject: [PATCH 136/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - code style fix --- app/code/Magento/Ui/view/base/web/js/form/element/abstract.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 3a4b7439bcc..6191a78d29a 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -76,10 +76,10 @@ define([ /** * Checks if component has error. + * * @returns {Boolean} */ isInvalid: function () { - return this.error() && this.error().length ? this : false; }, -- GitLab From 5f8f26f23d66208ffbb2cede65f4ce5bc4fafe70 Mon Sep 17 00:00:00 2001 From: Rykh Oleksandr <orykh@magento.com> Date: Thu, 4 Aug 2016 12:22:07 +0300 Subject: [PATCH 137/838] MTA-3342: Add an ability to run specified variation from a test case --- .../Magento/Mtf/TestSuite/InjectableTests.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php index 6c7e8b334ba..974e4ab89c2 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php @@ -98,8 +98,17 @@ class InjectableTests extends \PHPUnit_Framework_TestSuite /** @var \Magento\Mtf\Config\DataInterface $configData */ $configData = $objectManagerFactory->getObjectManager()->create(\Magento\Mtf\Config\TestRunner::class); - $configData->setFileName($configFileName . '.xml')->load($configFilePath); - + $filter = getopt('', ['filter:']); + if (!isset($filter['filter'])) { + $configData->setFileName($configFileName . '.xml')->load($configFilePath); + } else { + preg_match('`variation::(.*?)$`', $filter['filter'], $variation); + if (isset($variation[1]) && !empty($variation[1])) { + $configData->setFileName('basic.xml')->load($configFilePath); + $data['rule']['variation']['allow'][0]['name'][0]['value'] = $variation[1]; + $configData->merge($data); + } + } $this->objectManager = $objectManagerFactory->create( [\Magento\Mtf\Config\TestRunner::class => $configData] ); -- GitLab From 67ab1954097306e456f5bac175efbfa634f8d571 Mon Sep 17 00:00:00 2001 From: petterk <petterk@markant.no> Date: Thu, 4 Aug 2016 11:28:39 +0200 Subject: [PATCH 138/838] Fix 'Track your order' i18n. --- app/code/Magento/Shipping/i18n/en_US.csv | 1 + .../Shipping/view/frontend/layout/sales_guest_reorder.xml | 2 +- .../Magento/Shipping/view/frontend/layout/sales_guest_view.xml | 2 +- .../Shipping/view/frontend/layout/sales_order_reorder.xml | 2 +- .../Magento/Shipping/view/frontend/layout/sales_order_view.xml | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Shipping/i18n/en_US.csv b/app/code/Magento/Shipping/i18n/en_US.csv index 54d7c83e94c..b1eaa148177 100644 --- a/app/code/Magento/Shipping/i18n/en_US.csv +++ b/app/code/Magento/Shipping/i18n/en_US.csv @@ -179,3 +179,4 @@ City,City "Apply custom Shipping Policy","Apply custom Shipping Policy" "Shipping Policy","Shipping Policy" "Shipping Methods","Shipping Methods" +"Track your order","Track your order" diff --git a/app/code/Magento/Shipping/view/frontend/layout/sales_guest_reorder.xml b/app/code/Magento/Shipping/view/frontend/layout/sales_guest_reorder.xml index 15f2b45595e..caa7a9e5b75 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/sales_guest_reorder.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/sales_guest_reorder.xml @@ -10,7 +10,7 @@ <referenceBlock name="sales.order.view"> <block class="Magento\Shipping\Block\Tracking\Link" name="tracking-info-link" template="tracking/link.phtml"> <arguments> - <argument name="label" xsi:type="string">Track your order</argument> + <argument name="label" xsi:type="string" translate="true">Track your order</argument> </arguments> </block> </referenceBlock> diff --git a/app/code/Magento/Shipping/view/frontend/layout/sales_guest_view.xml b/app/code/Magento/Shipping/view/frontend/layout/sales_guest_view.xml index 15f2b45595e..caa7a9e5b75 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/sales_guest_view.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/sales_guest_view.xml @@ -10,7 +10,7 @@ <referenceBlock name="sales.order.view"> <block class="Magento\Shipping\Block\Tracking\Link" name="tracking-info-link" template="tracking/link.phtml"> <arguments> - <argument name="label" xsi:type="string">Track your order</argument> + <argument name="label" xsi:type="string" translate="true">Track your order</argument> </arguments> </block> </referenceBlock> diff --git a/app/code/Magento/Shipping/view/frontend/layout/sales_order_reorder.xml b/app/code/Magento/Shipping/view/frontend/layout/sales_order_reorder.xml index 15f2b45595e..caa7a9e5b75 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/sales_order_reorder.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/sales_order_reorder.xml @@ -10,7 +10,7 @@ <referenceBlock name="sales.order.view"> <block class="Magento\Shipping\Block\Tracking\Link" name="tracking-info-link" template="tracking/link.phtml"> <arguments> - <argument name="label" xsi:type="string">Track your order</argument> + <argument name="label" xsi:type="string" translate="true">Track your order</argument> </arguments> </block> </referenceBlock> diff --git a/app/code/Magento/Shipping/view/frontend/layout/sales_order_view.xml b/app/code/Magento/Shipping/view/frontend/layout/sales_order_view.xml index 15f2b45595e..caa7a9e5b75 100644 --- a/app/code/Magento/Shipping/view/frontend/layout/sales_order_view.xml +++ b/app/code/Magento/Shipping/view/frontend/layout/sales_order_view.xml @@ -10,7 +10,7 @@ <referenceBlock name="sales.order.view"> <block class="Magento\Shipping\Block\Tracking\Link" name="tracking-info-link" template="tracking/link.phtml"> <arguments> - <argument name="label" xsi:type="string">Track your order</argument> + <argument name="label" xsi:type="string" translate="true">Track your order</argument> </arguments> </block> </referenceBlock> -- GitLab From 19cd397fdae1471b7768e34e5fae21149cc86714 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 12:32:27 +0300 Subject: [PATCH 139/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../ResourceModel/BookmarkRepository.php | 46 ++++++----- .../ResourceModel/BookmarkRepositoryTest.php | 81 ++++--------------- .../Vault/Model/PaymentTokenRepository.php | 31 +++++-- .../Unit/Model/PaymentTokenRepositoryTest.php | 22 +++-- .../Magento/Ui/Api/BookmarkRepositoryTest.php | 79 ++++++++++++++++++ .../testsuite/Magento/Ui/_files/bookmarks.php | 40 +++++++++ .../Model/PaymentTokenRepositoryTest.php | 80 ++++++++++++++++++ .../Magento/Vault/_files/payment_tokens.php | 47 +++++++++++ 8 files changed, 329 insertions(+), 97 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php create mode 100644 dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php diff --git a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php index 150983825f6..eb9fa51472f 100644 --- a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php +++ b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php @@ -5,6 +5,8 @@ */ namespace Magento\Ui\Model\ResourceModel; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SortOrder; use Magento\Ui\Api\BookmarkRepositoryInterface; @@ -37,6 +39,11 @@ class BookmarkRepository implements BookmarkRepositoryInterface */ protected $searchResultsFactory; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param \Magento\Ui\Api\Data\BookmarkInterfaceFactory $bookmarkFactory * @param Bookmark $bookmarkResourceModel @@ -45,12 +52,14 @@ class BookmarkRepository implements BookmarkRepositoryInterface public function __construct( \Magento\Ui\Api\Data\BookmarkInterfaceFactory $bookmarkFactory, \Magento\Ui\Model\ResourceModel\Bookmark $bookmarkResourceModel, - \Magento\Ui\Api\Data\BookmarkSearchResultsInterfaceFactory $searchResultsFactory + \Magento\Ui\Api\Data\BookmarkSearchResultsInterfaceFactory $searchResultsFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->bookmarkResourceModel = $bookmarkResourceModel; $this->bookmarkFactory = $bookmarkFactory; $this->searchResultsFactory = $searchResultsFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -101,24 +110,8 @@ class BookmarkRepository implements BookmarkRepositoryInterface /** @var \Magento\Ui\Model\ResourceModel\Bookmark\Collection $collection */ $collection = $this->bookmarkFactory->create()->getCollection(); - // Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } + $this->collectionProcessor->process($searchCriteria, $collection); $searchResults->setTotalCount($collection->getSize()); - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders) { - /** @var SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $field = $sortOrder->getField(); - $collection->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); $bookmarks = []; /** @var BookmarkInterface $bookmark */ @@ -166,6 +159,7 @@ class BookmarkRepository implements BookmarkRepositoryInterface * @param FilterGroup $filterGroup * @param Collection $collection * @return void + * @deprecated * @throws \Magento\Framework\Exception\InputException */ protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) @@ -175,4 +169,20 @@ class BookmarkRepository implements BookmarkRepositoryInterface $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + CollectionProcessorComposite::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Ui/Test/Unit/Model/ResourceModel/BookmarkRepositoryTest.php b/app/code/Magento/Ui/Test/Unit/Model/ResourceModel/BookmarkRepositoryTest.php index 8a3d43354e8..9feb02072c1 100644 --- a/app/code/Magento/Ui/Test/Unit/Model/ResourceModel/BookmarkRepositoryTest.php +++ b/app/code/Magento/Ui/Test/Unit/Model/ResourceModel/BookmarkRepositoryTest.php @@ -36,6 +36,11 @@ class BookmarkRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $searchResultsMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * Set up */ @@ -64,11 +69,18 @@ class BookmarkRepositoryTest extends \PHPUnit_Framework_TestCase \Magento\Ui\Api\Data\BookmarkSearchResultsInterfaceFactory::class )->disableOriginalConstructor()->setMethods(['create'])->getMock(); $searchResultsFactoryMock->expects($this->any())->method('create')->willReturn($this->searchResultsMock); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->bookmarkRepository = new BookmarkRepository( $bookmarkFactoryMock, $this->bookmarkResourceMock, - $searchResultsFactoryMock + $searchResultsFactoryMock, + $this->collectionProcessor ); } @@ -143,10 +155,7 @@ class BookmarkRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { $bookmarkId = 1; - $fieldNameAsc = 'first_field'; - $fieldValueAsc = 'first_value'; - $fieldNameDesc = 'second_field'; - $fieldValueDesc = 'second_value'; + $this->bookmarkMock->expects($this->any()) ->method('getId') ->willReturn($bookmarkId); @@ -154,77 +163,17 @@ class BookmarkRepositoryTest extends \PHPUnit_Framework_TestCase ->method('load') ->with($this->bookmarkMock, $bookmarkId) ->willReturn($this->bookmarkMock); - $filterGroup = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class) - ->disableOriginalConstructor() - ->getMock(); - $sortOrderAsc = $this->getMockBuilder(\Magento\Framework\Api\SortOrder::class) - ->disableOriginalConstructor() - ->getMock(); - $sortOrderAsc->expects($this->once()) - ->method('getField') - ->willReturn($fieldNameAsc); - $sortOrderAsc->expects($this->once()) - ->method('getDirection') - ->willReturn(SortOrder::SORT_ASC); - $sortOrderDesc = $this->getMockBuilder(\Magento\Framework\Api\SortOrder::class) - ->disableOriginalConstructor() - ->getMock(); - $sortOrderDesc->expects($this->once()) - ->method('getField') - ->willReturn($fieldNameDesc); - $sortOrderDesc->expects($this->once()) - ->method('getDirection') - ->willReturn(SortOrder::SORT_DESC); - $fieldAsc = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $fieldAsc->expects($this->once()) - ->method('getField') - ->willReturn($fieldNameAsc); - $fieldAsc->expects($this->once()) - ->method('getValue') - ->willReturn($fieldValueAsc); - $fieldAsc->expects($this->any()) - ->method('getConditionType') - ->willReturn(false); - $fieldDesc = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $fieldDesc->expects($this->once()) - ->method('getField') - ->willReturn($fieldNameDesc); - $fieldDesc->expects($this->once()) - ->method('getValue') - ->willReturn($fieldValueDesc); - $fieldDesc->expects($this->any()) - ->method('getConditionType') - ->willReturn('eq'); - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$fieldAsc, $fieldDesc]); $collection = $this->getMockBuilder(\Magento\Ui\Model\ResourceModel\Bookmark\Collection::class) ->disableOriginalConstructor() ->getMock(); $collection->expects($this->once()) ->method('getItems') ->willReturn([$this->bookmarkMock]); - $collection->expects($this->any()) - ->method('addOrder') - ->willReturnMap([[$fieldNameAsc, SortOrder::SORT_ASC], [$fieldNameDesc, SortOrder::SORT_DESC]]); - $collection->expects($this->any()) - ->method('addFieldToFilter') - ->willReturnMap([[$fieldNameAsc, [$fieldValueAsc => 'eq']], [$fieldNameDesc, [$fieldValueDesc => 'eq']]]); $this->bookmarkMock->expects($this->once()) ->method('getCollection') ->willReturn($collection); $searchCriteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaInterface::class) ->getMockForAbstractClass(); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroup]); - $searchCriteria->expects($this->once()) - ->method('getSortOrders') - ->willReturn([$sortOrderAsc, $sortOrderDesc]); $this->assertEquals($this->searchResultsMock, $this->bookmarkRepository->getList($searchCriteria)); } diff --git a/app/code/Magento/Vault/Model/PaymentTokenRepository.php b/app/code/Magento/Vault/Model/PaymentTokenRepository.php index 38bc9608147..462fa0fe50f 100644 --- a/app/code/Magento/Vault/Model/PaymentTokenRepository.php +++ b/app/code/Magento/Vault/Model/PaymentTokenRepository.php @@ -7,6 +7,7 @@ namespace Magento\Vault\Model; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Vault\Api\Data; use Magento\Vault\Api\Data\PaymentTokenSearchResultsInterfaceFactory; @@ -51,6 +52,9 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface */ protected $collectionFactory; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * @param \Magento\Vault\Model\ResourceModel\PaymentToken $resourceModel * @param PaymentTokenFactory $paymentTokenFactory @@ -65,7 +69,8 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface FilterBuilder $filterBuilder, SearchCriteriaBuilder $searchCriteriaBuilder, PaymentTokenSearchResultsInterfaceFactory $searchResultsFactory, - CollectionFactory $collectionFactory + CollectionFactory $collectionFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->resourceModel = $resourceModel; $this->paymentTokenFactory = $paymentTokenFactory; @@ -73,6 +78,7 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->searchResultsFactory = $searchResultsFactory; $this->collectionFactory = $collectionFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -85,11 +91,7 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface { /** @var \Magento\Vault\Model\ResourceModel\PaymentToken\Collection $collection */ $collection = $this->collectionFactory->create(); - /** @var FilterGroup $group */ - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - + $this->collectionProcessor->process($searchCriteria, $collection); /** @var \Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface $searchResults */ $searchResults = $this->searchResultsFactory->create(); $searchResults->setSearchCriteria($searchCriteria); @@ -150,6 +152,7 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface * @param FilterGroup $filterGroup * @param Collection $collection * @return void + * @deprecated * @throws \Magento\Framework\Exception\InputException */ protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) @@ -159,4 +162,20 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php index 6ee6108f062..3cd54f7a125 100644 --- a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php +++ b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php @@ -76,6 +76,11 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $collectionMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * @return void */ @@ -123,7 +128,13 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->repositoryModel = $this->getMockBuilder(PaymentTokenRepository::class) ->setConstructorArgs([ 'resourceModel' => $this->resourceModelMock, @@ -131,7 +142,8 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase 'filterBuilder' => $this->filterBuilderMock, 'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock, 'searchResultsFactory' => $this->searchResultsFactoryMock, - 'collectionFactory' => $this->collectionFactoryMock + 'collectionFactory' => $this->collectionFactoryMock, + 'collectionProcessor' => $this->collectionProcessor ]) ->setMethods(null) ->getMock(); @@ -148,11 +160,7 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase $this->collectionFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->collectionMock); - - $this->searchCriteriaMock->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([]); - + $this->searchResultsFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->searchResults); diff --git a/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php new file mode 100644 index 00000000000..34b9e416eb6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php @@ -0,0 +1,79 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Api; + +use Magento\Ui\Model\ResourceModel\BookmarkRepository; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; + +/** + * Class CarrierTest + * @package Magento\Ups\Model + * @magentoDbIsolation enabled + */ +class BookmarkRepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** @var BookmarkRepository */ + private $repository; + + /** @var SortOrderBuilder */ + private $sortOrderBuilder; + + /** @var FilterBuilder */ + private $filterBuilder; + + /** @var SearchCriteriaBuilder */ + private $searchCriteriaBuilder; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->repository = $objectManager->create(BookmarkRepository::class); + $this->searchCriteriaBuilder = $objectManager->create( + \Magento\Framework\Api\SearchCriteriaBuilder::class + ); + $this->filterBuilder = $objectManager->get( + \Magento\Framework\Api\FilterBuilder::class + ); + $this->sortOrderBuilder = $objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); + } + + /** + * @magentoDataFixture Magento/Ui/_files/bookmarks.php + */ + public function testGetListWithMultipleFiltersAndSorting() + { + $filter1 = $this->filterBuilder + ->setField('namespace') + ->setValue('bm_namespace') + ->create(); + $filter2 = $this->filterBuilder + ->setField('namespace') + ->setValue('new_namespace') + ->create(); + $filter3 = $this->filterBuilder + ->setField('current') + ->setValue(1) + ->create(); + $sortOrder = $this->sortOrderBuilder + ->setField('title') + ->setDirection('DESC') + ->create(); + + $this->searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $this->searchCriteriaBuilder->addFilters([$filter3]); + $this->searchCriteriaBuilder->addSortOrder($sortOrder); + $searchCriteria = $this->searchCriteriaBuilder->create(); + /** @var \Magento\Ui\Api\Data\BookmarkSearchResultsInterface $result */ + $result = $this->repository->getList($searchCriteria); + $this->assertEquals(2, $result->getTotalCount()); + $this->assertEquals('Default View', $result->getItems()[0]->getTitle()); + $this->assertEquals('Bb', $result->getItems()[1]->getTitle()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php new file mode 100644 index 00000000000..015e291e8a9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php @@ -0,0 +1,40 @@ +<?php + +use Magento\Ui\Api\Data\BookmarkInterface; +use Magento\Ui\Model\Bookmark; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$bookmarks = [ + [ + 'user_id' => 1, + 'namespace' => 'bm_namespace', + 'identifier' => 'first', + 'current' => 1, + 'config' => '{}', + 'title' => 'Bb' + ], + [ + 'user_id' => 1, + 'namespace' => 'bm_namespace', + 'identifier' => 'second', + 'current' => 0, + 'config' => '{1}', + 'title' => 'Aa' + ], + [ + 'user_id' => 2, + 'namespace' => 'new_namespace', + 'identifier' => 'third', + 'current' => 1, + 'config' => '{}', + 'title' => 'Default View' + ], +]; + +foreach($bookmarks as $bookmarkData) { + /** @var Bookmark $bookmark */ + $bookmark = $objectManager->create(BookmarkInterface::class); + $bookmark + ->setData($bookmarkData) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php new file mode 100644 index 00000000000..b95afa7db43 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php @@ -0,0 +1,80 @@ +<?php +/*** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Vault\Model; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; + +/** + * Class PaymentTokenRepositoryTest + * @package Magento\Vault\Model + * @magentoDbIsolation enabled + */ +class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** @var PaymentTokenRepository */ + private $repository; + + /** @var SortOrderBuilder */ + private $sortOrderBuilder; + + /** @var FilterBuilder */ + private $filterBuilder; + + /** @var SearchCriteriaBuilder */ + private $searchCriteriaBuilder; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->repository = $objectManager->create(PaymentTokenRepository::class); + $this->searchCriteriaBuilder = $objectManager->create( + \Magento\Framework\Api\SearchCriteriaBuilder::class + ); + $this->filterBuilder = $objectManager->get( + \Magento\Framework\Api\FilterBuilder::class + ); + $this->sortOrderBuilder = $objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); + } + + /** + * @magentoDataFixture Magento/Vault/_files/payment_tokens.php + */ + public function testGetListWithMultipleFiltersAndSorting() + { + $filter1 = $this->filterBuilder + ->setField('type') + ->setValue('simple') + ->create(); + $filter2 = $this->filterBuilder + ->setField('is_active') + ->setValue(1) + ->create(); + $filter3 = $this->filterBuilder + ->setField('expires_at') + ->setConditionType('lt') + ->setValue('2016-11-04 10:18:15') + ->create(); + $sortOrder = $this->sortOrderBuilder + ->setField('customer_id') + ->setDirection('DESC') + ->create(); + + $this->searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $this->searchCriteriaBuilder->addFilters([$filter3]); + $this->searchCriteriaBuilder->addSortOrder($sortOrder); + $searchCriteria = $this->searchCriteriaBuilder->create(); + /** @var \Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface $result */ + $result = $this->repository->getList($searchCriteria); + $items = $result->getItems(); + $this->assertCount(2, $items); + $this->assertEquals('second', array_shift($items)->getPaymentMethodCode()); + $this->assertEquals('first', array_shift($items)->getPaymentMethodCode()); + } +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php new file mode 100644 index 00000000000..bca18b68755 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php @@ -0,0 +1,47 @@ +<?php + +use Magento\Vault\Model\PaymentToken; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$paymentTokens = [ + [ + 'customer_id' => 1, + 'public_hash' => '1234', + 'payment_method_code' => 'first', + 'type' => 'simple', + 'expires_at' => '2016-09-04 10:18:15', + 'is_active' => 1 + ], + [ + 'customer_id' => 2, + 'public_hash' => '12345', + 'payment_method_code' => 'second', + 'type' => 'simple', + 'expires_at' => '2016-10-04 10:18:15', + 'is_active' => 1 + ], + [ + 'customer_id' => 1, + 'public_hash' => '23456', + 'payment_method_code' => 'third', + 'type' => 'notsimple', + 'expires_at' => '2016-11-04 10:18:15', + 'is_active' => 1 + ], + [ + 'customer_id' => 1, + 'public_hash' => '234567', + 'payment_method_code' => 'fourth', + 'type' => 'simple', + 'expires_at' => '2016-12-04 10:18:15', + 'is_active' => 0 + ], +]; +/** @var array $tokenData */ +foreach($paymentTokens as $tokenData) { + /** @var PaymentToken $bookmark */ + $paymentToken = $objectManager->create(PaymentToken::class); + $paymentToken + ->setData($tokenData) + ->save(); +} -- GitLab From 3750a9b30cce785624b0cd5e02443ae422503b60 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:03:48 +0300 Subject: [PATCH 140/838] MAGETWO-56004: Remove wishlist observer \Magento\Wishlist\Observer\AddToCart --- app/code/Magento/Wishlist/Observer/AddToCart.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Wishlist/Observer/AddToCart.php b/app/code/Magento/Wishlist/Observer/AddToCart.php index 12eca7dc80a..19e784ef369 100644 --- a/app/code/Magento/Wishlist/Observer/AddToCart.php +++ b/app/code/Magento/Wishlist/Observer/AddToCart.php @@ -15,6 +15,7 @@ use Magento\Wishlist\Model\WishlistFactory; /** * Class AddToCart + * @deprecated * @package Magento\Wishlist\Observer */ class AddToCart implements ObserverInterface -- GitLab From d95772958c90b7cad5e7f3f46764ac0b51afa49f Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:04:31 +0300 Subject: [PATCH 141/838] MAGETWO-56005: Eliminate getTemplateTypes method --- .../Customer/Model/EmailNotification.php | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Customer/Model/EmailNotification.php b/app/code/Magento/Customer/Model/EmailNotification.php index 4f362ccada6..1aed513ef07 100644 --- a/app/code/Magento/Customer/Model/EmailNotification.php +++ b/app/code/Magento/Customer/Model/EmailNotification.php @@ -43,6 +43,23 @@ class EmailNotification implements EmailNotificationInterface const XML_PATH_CONFIRM_EMAIL_TEMPLATE = 'customer/create_account/email_confirmation_template'; const XML_PATH_CONFIRMED_EMAIL_TEMPLATE = 'customer/create_account/email_confirmed_template'; + + /** + * self::NEW_ACCOUNT_EMAIL_REGISTERED welcome email, when confirmation is disabled + * and password is set + * self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD welcome email, when confirmation is disabled + * and password is not set + * self::NEW_ACCOUNT_EMAIL_CONFIRMED welcome email, when confirmation is enabled + * and password is set + * self::NEW_ACCOUNT_EMAIL_CONFIRMATION email with confirmation link + */ + const TEMPLATE_TYPES = [ + self::NEW_ACCOUNT_EMAIL_REGISTERED => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, + self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD => self::XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE, + self::NEW_ACCOUNT_EMAIL_CONFIRMED => self::XML_PATH_CONFIRMED_EMAIL_TEMPLATE, + self::NEW_ACCOUNT_EMAIL_CONFIRMATION => self::XML_PATH_CONFIRM_EMAIL_TEMPLATE, + ]; + /**#@-*/ /** @@ -339,7 +356,7 @@ class EmailNotification implements EmailNotificationInterface $storeId = 0, $sendemailStoreId = null ) { - $types = $this->getTemplateTypes(); + $types = self::TEMPLATE_TYPES; if (!isset($types[$type])) { throw new LocalizedException(__('Please correct the transactional account email type.')); @@ -361,30 +378,4 @@ class EmailNotification implements EmailNotificationInterface $storeId ); } - - /** - * Get template types - * - * @return array - * @todo: consider eliminating method - */ - private function getTemplateTypes() - { - /** - * self::NEW_ACCOUNT_EMAIL_REGISTERED welcome email, when confirmation is disabled - * and password is set - * self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD welcome email, when confirmation is disabled - * and password is not set - * self::NEW_ACCOUNT_EMAIL_CONFIRMED welcome email, when confirmation is enabled - * and password is set - * self::NEW_ACCOUNT_EMAIL_CONFIRMATION email with confirmation link - */ - $types = [ - self::NEW_ACCOUNT_EMAIL_REGISTERED => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, - self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD => self::XML_PATH_REGISTER_NO_PASSWORD_EMAIL_TEMPLATE, - self::NEW_ACCOUNT_EMAIL_CONFIRMED => self::XML_PATH_CONFIRMED_EMAIL_TEMPLATE, - self::NEW_ACCOUNT_EMAIL_CONFIRMATION => self::XML_PATH_CONFIRM_EMAIL_TEMPLATE, - ]; - return $types; - } } -- GitLab From a5e2821c9137a37a2d0d3ce36af2b41b0b62f5fe Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:05:02 +0300 Subject: [PATCH 142/838] MAGETWO-56006: Implement unsRegion method --- .../Magento/Customer/Model/Address/AbstractAddress.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 1851f858b99..b79034c019e 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -629,4 +629,12 @@ class AbstractAddress extends AbstractExtensibleModel implements AddressModelInt { return $this->_countryFactory->create(); } + + /** + * @return $this + */ + public function unsRegion() + { + return $this->unsetData("region"); + } } -- GitLab From f70b3a51eaf3678aa09331ecaa4ab3b5114bcec9 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:05:34 +0300 Subject: [PATCH 143/838] MAGETWO-56009: Handle external usages of customer methods and remove them in \Magento\Quote\Model\Quote --- app/code/Magento/Quote/Model/Quote.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php index b97e15e5e53..6d6529c4fb7 100644 --- a/app/code/Magento/Quote/Model/Quote.php +++ b/app/code/Magento/Quote/Model/Quote.php @@ -841,6 +841,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C * Loading quote data by customer * * @param \Magento\Customer\Model\Customer|int $customer + * @deprecated * @return $this */ public function loadByCustomer($customer) -- GitLab From bffbba36a2e40517542048d295a011567f67dd88 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:05:59 +0300 Subject: [PATCH 144/838] MAGETWO-56010: Remove password validation class duplicate --- .../Customer/Model/Customer/Attribute/Backend/Password.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Customer/Model/Customer/Attribute/Backend/Password.php b/app/code/Magento/Customer/Model/Customer/Attribute/Backend/Password.php index df55cd1c3f0..337cefd8b99 100644 --- a/app/code/Magento/Customer/Model/Customer/Attribute/Backend/Password.php +++ b/app/code/Magento/Customer/Model/Customer/Attribute/Backend/Password.php @@ -8,6 +8,7 @@ namespace Magento\Customer\Model\Customer\Attribute\Backend; use Magento\Framework\Exception\LocalizedException; /** + * @deprecated * Customer password attribute backend */ class Password extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend @@ -62,6 +63,7 @@ class Password extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBacke } /** + * @deprecated * @param \Magento\Framework\DataObject $object * @return bool */ -- GitLab From 5aa74f9bea010ef303841b051058044616669543 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:27:34 +0300 Subject: [PATCH 145/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php | 1 + .../Magento/Ui/Model/ResourceModel/BookmarkRepository.php | 1 + app/code/Magento/Vault/Model/PaymentTokenRepository.php | 3 ++- .../Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php | 6 ++++++ .../integration/testsuite/Magento/Ui/_files/bookmarks.php | 2 +- .../Magento/Vault/Model/PaymentTokenRepositoryTest.php | 2 +- .../testsuite/Magento/Vault/_files/payment_tokens.php | 2 +- 7 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index ce34306b4be..124104b9731 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -417,6 +417,7 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetListSuccess() { + $this->markTestSkipped('MAGETWO-48531'); $searchResult = $this->getMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class, [], [], '', false); $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); $cartMock = $this->getMock(\Magento\Payment\Model\Cart::class, [], [], '', false); diff --git a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php index eb9fa51472f..16776369667 100644 --- a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php +++ b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php @@ -48,6 +48,7 @@ class BookmarkRepository implements BookmarkRepositoryInterface * @param \Magento\Ui\Api\Data\BookmarkInterfaceFactory $bookmarkFactory * @param Bookmark $bookmarkResourceModel * @param \Magento\Ui\Api\Data\BookmarkSearchResultsInterfaceFactory $searchResultsFactory + * @param CollectionProcessorInterface | null $collectionProcessor */ public function __construct( \Magento\Ui\Api\Data\BookmarkInterfaceFactory $bookmarkFactory, diff --git a/app/code/Magento/Vault/Model/PaymentTokenRepository.php b/app/code/Magento/Vault/Model/PaymentTokenRepository.php index 462fa0fe50f..0cc17c3011e 100644 --- a/app/code/Magento/Vault/Model/PaymentTokenRepository.php +++ b/app/code/Magento/Vault/Model/PaymentTokenRepository.php @@ -62,6 +62,7 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param PaymentTokenSearchResultsInterfaceFactory $searchResultsFactory * @param CollectionFactory $collectionFactory + * @param CollectionProcessorInterface | null $collectionProcessor */ public function __construct( PaymentTokenResourceModel $resourceModel, @@ -91,7 +92,7 @@ class PaymentTokenRepository implements PaymentTokenRepositoryInterface { /** @var \Magento\Vault\Model\ResourceModel\PaymentToken\Collection $collection */ $collection = $this->collectionFactory->create(); - $this->collectionProcessor->process($searchCriteria, $collection); + $this->collectionProcessor->process($searchCriteria, $collection); /** @var \Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface $searchResults */ $searchResults = $this->searchResultsFactory->create(); $searchResults->setSearchCriteria($searchCriteria); diff --git a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php index 3cd54f7a125..59d79a7fc27 100644 --- a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php +++ b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php @@ -18,9 +18,15 @@ use Magento\Vault\Model\ResourceModel\PaymentToken\CollectionFactory; use PHPUnit_Framework_MockObject_MockObject as MockObject; use Magento\Vault\Model\ResourceModel\PaymentToken as PaymentTokenResourceModel; +/** + * Class PaymentTokenRepositoryTest + * @package Magento\Vault\Test\Unit\Model + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase { const PUBLIC_HASH = 'hash'; + /** * @var \Magento\Vault\Model\PaymentTokenRepository|MockObject resourceModelMock */ diff --git a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php index 015e291e8a9..f95762248cb 100644 --- a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php +++ b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php @@ -31,7 +31,7 @@ $bookmarks = [ ], ]; -foreach($bookmarks as $bookmarkData) { +foreach ($bookmarks as $bookmarkData) { /** @var Bookmark $bookmark */ $bookmark = $objectManager->create(BookmarkInterface::class); $bookmark diff --git a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php index b95afa7db43..2aef540d847 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php @@ -77,4 +77,4 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase $this->assertEquals('second', array_shift($items)->getPaymentMethodCode()); $this->assertEquals('first', array_shift($items)->getPaymentMethodCode()); } -} \ No newline at end of file +} diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php index bca18b68755..45657b824e1 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php @@ -38,7 +38,7 @@ $paymentTokens = [ ], ]; /** @var array $tokenData */ -foreach($paymentTokens as $tokenData) { +foreach ($paymentTokens as $tokenData) { /** @var PaymentToken $bookmark */ $paymentToken = $objectManager->create(PaymentToken::class); $paymentToken -- GitLab From 16ce034c6a2b9af40a066dda5a3e6264da158472 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Thu, 4 Aug 2016 13:28:19 +0300 Subject: [PATCH 146/838] MAGETWO-55364: [WCAG 2.0 AA] Add Aria-Labels for Color Swatches - CR changes --- .../view/frontend/web/js/swatch-renderer.js | 54 +++++++++++-------- lib/web/mage/smart-keyboard-handler.js | 10 ++-- lib/web/mage/validation.js | 9 +++- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 318b2b7066b..75fb9c73264 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -13,36 +13,46 @@ define([ ], function ($, _, keyboardHandler) { 'use strict'; + /** + * Extend form validation to support swatch accessibility + */ $.widget('mage.validation', $.mage.validation, { + /** + * Handle form with swatches validation + * + * @param {Object} event + * @param {Object} validation + */ listenFormValidateHandler: function (event, validation) { + var swatchWrapper, firstActive, swatches, swatch, successList, errorList, firstSwatch; + this._superApply(arguments); - var swatchWrapper = $.mage.SwatchRenderer().options.classes.attributeOptionsWrapper, - firstActive = $(validation.errorList[0].element || []), - swatches = $(this).find('.' + swatchWrapper); + swatchWrapper = '.swatch-attribute-options'; + swatches = $(event.target).find(swatchWrapper); + + if (!swatches.length) { + return; + } - if(swatches.length){ - var successList = validation.successList, - errorList = validation.errorList, - firstSwatch = $(firstActive).parent().find('.' + swatchWrapper); + swatch = '.swatch-attribute'; + firstActive = $(validation.errorList[0].element || []); + successList = validation.successList; + errorList = validation.errorList; + firstSwatch = $(firstActive).parent(swatch).find(swatchWrapper); - keyboardHandler.focus(swatches); + keyboardHandler.focus(swatches); - if (successList.length) { - $.each(successList, function () { - $(this).parent().find('.' + swatchWrapper).attr('aria-invalid', false); - }) - } + $.each(successList, function (index, item) { + $(item).parent(swatch).find(swatchWrapper).attr('aria-invalid', false); + }); - if (errorList.length) { - $.each(errorList, function (index, item) { - $(item.element).parent().find('.' + swatchWrapper).attr('aria-invalid', true); - }) - } + $.each(errorList, function (index, item) { + $(item.element).parent(swatch).find(swatchWrapper).attr('aria-invalid', true); + }); - if(firstSwatch.length){ - $(firstSwatch) .focus(); - } + if (firstSwatch.length) { + $(firstSwatch).focus(); } } }); @@ -316,7 +326,7 @@ define([ options = $widget._RenderSwatchOptions(item, controlLabelId), select = $widget._RenderSwatchSelect(item, chooseText), input = $widget._RenderFormInput(item), - listLabel ='', + listLabel = '', label = ''; // Show only swatch controls diff --git a/lib/web/mage/smart-keyboard-handler.js b/lib/web/mage/smart-keyboard-handler.js index 9a7e00afe7d..b6a65f2ee5d 100644 --- a/lib/web/mage/smart-keyboard-handler.js +++ b/lib/web/mage/smart-keyboard-handler.js @@ -50,7 +50,7 @@ define([ * Handle logic, when onTabKeyPress fired at first. * Then it changes state. */ - function onFocusInHandler () { + function onFocusInHandler() { focusState = true; body.addClass(tabFocusClass) .off('focusin.keyboardHandler', onFocusInHandler); @@ -67,17 +67,19 @@ define([ /** * Attach smart focus on specific element. - * @param {HTMLElement} element + * @param {jQuery} element */ function handleFocus(element) { - element.on('focusin', function () { + element.on('focusin.emulateTabFocus', function () { focusState = true; body.addClass(tabFocusClass); + element.off(); }); - element.on('focusout', function () { + element.on('focusout.emulateTabFocus', function () { focusState = false; body.removeClass(tabFocusClass); + element.off(); }); } } diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index d3afca0ea8a..79ac8f42fee 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1538,7 +1538,12 @@ _listenFormValidate: function () { $('form').on('invalid-form.validate', this.listenFormValidateHandler); }, - + /** + * Handle form validation + * + * @param {Object} event + * @param {Object} validation + */ listenFormValidateHandler: function (event, validation) { var firstActive = $(validation.errorList[0].element || []), lastActive = $(validation.findLastActive() || validation.errorList.length && validation.errorList[0].element || []); @@ -1558,7 +1563,7 @@ $(this) .removeAttr('aria-describedby') .removeAttr('aria-invalid'); - }) + }); } if (firstActive.length) { firstActive.focus(); -- GitLab From 5d970fbd9fc33200931013379b29fd5156cd348c Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 13:50:08 +0300 Subject: [PATCH 147/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../integration/testsuite/Magento/Ui/_files/bookmarks.php | 5 ++++- .../testsuite/Magento/Vault/_files/payment_tokens.php | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php index f95762248cb..be7754ab0a3 100644 --- a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php +++ b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ use Magento\Ui\Api\Data\BookmarkInterface; use Magento\Ui\Model\Bookmark; diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php index 45657b824e1..f75f78d2dd2 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ use Magento\Vault\Model\PaymentToken; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -- GitLab From 02ad8b448cf625e1562da5dc48484c25591ecc86 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 15:22:43 +0300 Subject: [PATCH 148/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../Vault/Model/PaymentTokenManagement.php | 51 +++++++++++-------- .../Unit/Model/PaymentTokenManagementTest.php | 4 +- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Vault/Model/PaymentTokenManagement.php b/app/code/Magento/Vault/Model/PaymentTokenManagement.php index 510dc4cea31..f4a445b35fb 100644 --- a/app/code/Magento/Vault/Model/PaymentTokenManagement.php +++ b/app/code/Magento/Vault/Model/PaymentTokenManagement.php @@ -128,26 +128,37 @@ class PaymentTokenManagement implements PaymentTokenManagementInterface */ public function getVisibleAvailableTokens($customerId) { - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::CUSTOMER_ID) - ->setValue($customerId) - ->create(); - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::IS_VISIBLE) - ->setValue(1) - ->create(); - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::IS_ACTIVE) - ->setValue(1) - ->create(); - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::EXPIRES_AT) - ->setConditionType('gt') - ->setValue( - $this->dateTimeFactory->create( - 'now', - new \DateTimeZone('UTC') - )->format('Y-m-d 00:00:00') - ) - ->create(); - $searchCriteria = $this->searchCriteriaBuilder->addFilters($filters) - ->create(); + $customerFilter = [ + $this->filterBuilder->setField(PaymentTokenInterface::CUSTOMER_ID) + ->setValue($customerId) + ->create() + ]; + $visibleFilter = [ + $this->filterBuilder->setField(PaymentTokenInterface::IS_VISIBLE) + ->setValue(1) + ->create() + ]; + $isActiveFilter = [ + $this->filterBuilder->setField(PaymentTokenInterface::IS_ACTIVE) + ->setValue(1) + ->create() + ]; + $expiresAtFilter = [ + $this->filterBuilder->setField(PaymentTokenInterface::EXPIRES_AT) + ->setConditionType('gt') + ->setValue( + $this->dateTimeFactory->create( + 'now', + new \DateTimeZone('UTC') + )->format('Y-m-d 00:00:00') + ) + ->create() + ]; + $this->searchCriteriaBuilder->addFilters($customerFilter); + $this->searchCriteriaBuilder->addFilters($visibleFilter); + $this->searchCriteriaBuilder->addFilters($isActiveFilter); + // add filters to different filter groups in order to filter by AND expression + $searchCriteria = $this->searchCriteriaBuilder->addFilters($expiresAtFilter)->create(); return $this->paymentTokenRepository->getList($searchCriteria)->getItems(); } diff --git a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenManagementTest.php b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenManagementTest.php index 4672ebac40c..8784522a80f 100644 --- a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenManagementTest.php +++ b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenManagementTest.php @@ -486,9 +486,9 @@ class PaymentTokenManagementTest extends \PHPUnit_Framework_TestCase ->with('Y-m-d 00:00:00') ->willReturn('2015-01-01 00:00:00'); - $this->searchCriteriaBuilder->expects(self::once()) + $this->searchCriteriaBuilder->expects(self::exactly(4)) ->method('addFilters') - ->with([$customerFilter, $visibilityFilter, $isActiveFilter, $expiresAtFilter]) + ->withConsecutive($customerFilter, $visibilityFilter, $isActiveFilter, $expiresAtFilter) ->willReturnSelf(); $this->searchCriteriaBuilder->expects(self::once()) -- GitLab From 81861f898e1d8db52dd455683df3e0303009f53f Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 15:40:30 +0300 Subject: [PATCH 149/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../Magento/Ui/Api/BookmarkRepositoryTest.php | 2 +- .../testsuite/Magento/Ui/_files/bookmarks.php | 2 +- .../Model/PaymentTokenRepositoryTest.php | 2 +- .../Magento/Vault/_files/customer.php | 34 +++++++++++++++++++ .../Magento/Vault/_files/payment_tokens.php | 6 +++- 5 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Vault/_files/customer.php diff --git a/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php index 34b9e416eb6..576cb3eaffe 100644 --- a/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Ui/Api/BookmarkRepositoryTest.php @@ -72,7 +72,7 @@ class BookmarkRepositoryTest extends \PHPUnit_Framework_TestCase $searchCriteria = $this->searchCriteriaBuilder->create(); /** @var \Magento\Ui\Api\Data\BookmarkSearchResultsInterface $result */ $result = $this->repository->getList($searchCriteria); - $this->assertEquals(2, $result->getTotalCount()); + $this->assertCount(2, $result->getItems()); $this->assertEquals('Default View', $result->getItems()[0]->getTitle()); $this->assertEquals('Bb', $result->getItems()[1]->getTitle()); } diff --git a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php index be7754ab0a3..046c833e1d6 100644 --- a/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php +++ b/dev/tests/integration/testsuite/Magento/Ui/_files/bookmarks.php @@ -25,7 +25,7 @@ $bookmarks = [ 'title' => 'Aa' ], [ - 'user_id' => 2, + 'user_id' => 1, 'namespace' => 'new_namespace', 'identifier' => 'third', 'current' => 1, diff --git a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php index 2aef540d847..59e4fa29e1f 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php @@ -62,7 +62,7 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase ->setValue('2016-11-04 10:18:15') ->create(); $sortOrder = $this->sortOrderBuilder - ->setField('customer_id') + ->setField('public_hash') ->setDirection('DESC') ->create(); diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/customer.php b/dev/tests/integration/testsuite/Magento/Vault/_files/customer.php new file mode 100644 index 00000000000..4a799bb4575 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/customer.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +use Magento\Customer\Model\CustomerRegistry; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +/** @var $repository \Magento\Customer\Api\CustomerRepositoryInterface */ +$repository = $objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); +$customer = $objectManager->create(\Magento\Customer\Model\Customer::class); +/** @var CustomerRegistry $customerRegistry */ +$customerRegistry = $objectManager->get(CustomerRegistry::class); +/** @var Magento\Customer\Model\Customer $customer */ +$customer->setWebsiteId(1) + ->setId(1) + ->setEmail('customer@example.com') + ->setPassword('password') + ->setGroupId(1) + ->setStoreId(1) + ->setIsActive(1) + ->setPrefix('Mr.') + ->setFirstname('John') + ->setMiddlename('A') + ->setLastname('Smith') + ->setSuffix('Esq.') + ->setDefaultBilling(1) + ->setDefaultShipping(1) + ->setTaxvat('12') + ->setGender(0); + +$customer->isObjectNew(true); +$customer->save(); +$customerRegistry->remove($customer->getId()); diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php index f75f78d2dd2..7185d224e33 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php @@ -3,6 +3,10 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +include "customer.php"; + +use Magento\Customer\Model\Customer; use Magento\Vault\Model\PaymentToken; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -16,7 +20,7 @@ $paymentTokens = [ 'is_active' => 1 ], [ - 'customer_id' => 2, + 'customer_id' => 1, 'public_hash' => '12345', 'payment_method_code' => 'second', 'type' => 'simple', -- GitLab From c2e5cfb649410b2f084e7cdc80ffb20260f9b9ca Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 4 Aug 2016 16:28:40 +0300 Subject: [PATCH 150/838] MAGETWO-56081: SearchCriteria Unified Processing for autogenerated repositories of Sales modules --- .../ResourceModel/Order/Invoice/Item.php | 5 +- ...editmemoCommentRepositoryInterfaceTest.php | 77 ++++++++++++ .../CreditmemoItemRepositoryInterfaceTest.php | 78 ++++++++++++ .../InvoiceCommentRepositoryInterfaceTest.php | 77 ++++++++++++ .../InvoiceItemRepositoryInterfaceTest.php | 78 ++++++++++++ ...erStatusHistoryRepositoryInterfaceTest.php | 77 ++++++++++++ ...ShipmentCommentRepositoryInterfaceTest.php | 77 ++++++++++++ .../ShipmentItemRepositoryInterfaceTest.php | 78 ++++++++++++ .../ShipmentTrackRepositoryInterfaceTest.php | 82 +++++++++++++ .../_files/creditmemo_comments_for_search.php | 66 ++++++++++ .../_files/creditmemo_items_for_search.php | 108 ++++++++++++++++ .../_files/invoice_comments_for_search.php | 65 ++++++++++ .../Sales/_files/invoice_items_for_search.php | 111 +++++++++++++++++ .../order_status_history_for_search.php | 49 ++++++++ .../_files/shipment_comments_for_search.php | 71 +++++++++++ .../_files/shipment_items_for_search.php | 116 ++++++++++++++++++ .../_files/shipment_tracks_for_search.php | 90 ++++++++++++++ 17 files changed, 1304 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoCommentRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoItemRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceCommentRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceItemRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/OrderStatusHistoryRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentCommentRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentItemRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentTrackRepositoryInterfaceTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_comments_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_items_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/invoice_comments_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/invoice_items_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_status_history_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/shipment_comments_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/shipment_items_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/shipment_tracks_for_search.php diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Item.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Item.php index 821819b9974..08002c2b19a 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Item.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Invoice/Item.php @@ -5,12 +5,15 @@ */ namespace Magento\Sales\Model\ResourceModel\Order\Invoice; +use Magento\Sales\Model\ResourceModel\EntityAbstract as SalesResource; +use Magento\Sales\Model\Spi\InvoiceItemResourceInterface; + /** * Flat sales order invoice item resource * * @author Magento Core Team <core@magentocommerce.com> */ -class Item extends \Magento\Sales\Model\ResourceModel\EntityAbstract +class Item extends SalesResource implements InvoiceItemResourceInterface { /** * Event prefix diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoCommentRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoCommentRepositoryInterfaceTest.php new file mode 100644 index 00000000000..f4089aadaa6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoCommentRepositoryInterfaceTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\CreditmemoCommentInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class CreditmemoCommentRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var CreditmemoCommentRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(CreditmemoCommentRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/creditmemo_comments_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(CreditmemoCommentInterface::COMMENT) + ->setValue('comment 2') + ->create(); + $filter2 = $filterBuilder->setField(CreditmemoCommentInterface::COMMENT) + ->setValue('comment 3') + ->create(); + $filter3 = $filterBuilder->setField(CreditmemoCommentInterface::COMMENT) + ->setValue('comment 4') + ->create(); + $filter4 = $filterBuilder->setField(CreditmemoCommentInterface::COMMENT) + ->setValue('comment 5') + ->create(); + $filter5 = $filterBuilder->setField(CreditmemoCommentInterface::IS_VISIBLE_ON_FRONT) + ->setValue(1) + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(CreditmemoCommentInterface::COMMENT) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('comment 2', $items[0][CreditmemoCommentInterface::COMMENT]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoItemRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoItemRepositoryInterfaceTest.php new file mode 100644 index 00000000000..93383295423 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/CreditmemoItemRepositoryInterfaceTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\CreditmemoItemInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class CreditmemoItemRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var CreditmemoItemRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(CreditmemoItemRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/creditmemo_items_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(CreditmemoItemInterface::NAME) + ->setValue('item 2') + ->create(); + $filter2 = $filterBuilder->setField(CreditmemoItemInterface::NAME) + ->setValue('item 3') + ->create(); + $filter3 = $filterBuilder->setField(CreditmemoItemInterface::NAME) + ->setValue('item 4') + ->create(); + $filter4 = $filterBuilder->setField(CreditmemoItemInterface::NAME) + ->setValue('item 5') + ->create(); + $filter5 = $filterBuilder->setField(CreditmemoItemInterface::PRICE) + ->setValue(45) + ->setConditionType('lt') + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(CreditmemoItemInterface::NAME) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('item 2', $items[0][CreditmemoItemInterface::NAME]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceCommentRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceCommentRepositoryInterfaceTest.php new file mode 100644 index 00000000000..5cf0cde4f1f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceCommentRepositoryInterfaceTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\InvoiceCommentInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class InvoiceCommentRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var InvoiceCommentRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(InvoiceCommentRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/invoice_comments_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(InvoiceCommentInterface::COMMENT) + ->setValue('comment 2') + ->create(); + $filter2 = $filterBuilder->setField(InvoiceCommentInterface::COMMENT) + ->setValue('comment 3') + ->create(); + $filter3 = $filterBuilder->setField(InvoiceCommentInterface::COMMENT) + ->setValue('comment 4') + ->create(); + $filter4 = $filterBuilder->setField(InvoiceCommentInterface::COMMENT) + ->setValue('comment 5') + ->create(); + $filter5 = $filterBuilder->setField(InvoiceCommentInterface::IS_VISIBLE_ON_FRONT) + ->setValue(1) + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(InvoiceCommentInterface::COMMENT) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('comment 2', $items[0][InvoiceCommentInterface::COMMENT]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceItemRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceItemRepositoryInterfaceTest.php new file mode 100644 index 00000000000..7f7f64e897b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/InvoiceItemRepositoryInterfaceTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\InvoiceItemInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class InvoiceItemRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var InvoiceItemRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(InvoiceItemRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/invoice_items_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(InvoiceItemInterface::NAME) + ->setValue('item 2') + ->create(); + $filter2 = $filterBuilder->setField(InvoiceItemInterface::NAME) + ->setValue('item 3') + ->create(); + $filter3 = $filterBuilder->setField(InvoiceItemInterface::NAME) + ->setValue('item 4') + ->create(); + $filter4 = $filterBuilder->setField(InvoiceItemInterface::NAME) + ->setValue('item 5') + ->create(); + $filter5 = $filterBuilder->setField(InvoiceItemInterface::PRICE) + ->setValue(45) + ->setConditionType('lt') + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(InvoiceItemInterface::NAME) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('item 2', $items[0][InvoiceItemInterface::NAME]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/OrderStatusHistoryRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/OrderStatusHistoryRepositoryInterfaceTest.php new file mode 100644 index 00000000000..5dd28b5603d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/OrderStatusHistoryRepositoryInterfaceTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\OrderStatusHistoryInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class OrderStatusHistoryRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var OrderStatusHistoryRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(OrderStatusHistoryRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_status_history_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(OrderStatusHistoryInterface::COMMENT) + ->setValue('comment 2') + ->create(); + $filter2 = $filterBuilder->setField(OrderStatusHistoryInterface::COMMENT) + ->setValue('comment 3') + ->create(); + $filter3 = $filterBuilder->setField(OrderStatusHistoryInterface::COMMENT) + ->setValue('comment 4') + ->create(); + $filter4 = $filterBuilder->setField(OrderStatusHistoryInterface::COMMENT) + ->setValue('comment 5') + ->create(); + $filter5 = $filterBuilder->setField(OrderStatusHistoryInterface::IS_VISIBLE_ON_FRONT) + ->setValue(1) + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(OrderStatusHistoryInterface::COMMENT) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('comment 2', $items[0][OrderStatusHistoryInterface::COMMENT]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentCommentRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentCommentRepositoryInterfaceTest.php new file mode 100644 index 00000000000..14784958c00 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentCommentRepositoryInterfaceTest.php @@ -0,0 +1,77 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\ShipmentCommentInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class ShipmentCommentRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ShipmentCommentRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(ShipmentCommentRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/shipment_comments_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(ShipmentCommentInterface::COMMENT) + ->setValue('comment 2') + ->create(); + $filter2 = $filterBuilder->setField(ShipmentCommentInterface::COMMENT) + ->setValue('comment 3') + ->create(); + $filter3 = $filterBuilder->setField(ShipmentCommentInterface::COMMENT) + ->setValue('comment 4') + ->create(); + $filter4 = $filterBuilder->setField(ShipmentCommentInterface::COMMENT) + ->setValue('comment 5') + ->create(); + $filter5 = $filterBuilder->setField(ShipmentCommentInterface::IS_VISIBLE_ON_FRONT) + ->setValue(1) + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(ShipmentCommentInterface::COMMENT) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('comment 2', $items[0][ShipmentCommentInterface::COMMENT]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentItemRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentItemRepositoryInterfaceTest.php new file mode 100644 index 00000000000..e0d5799c6c7 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentItemRepositoryInterfaceTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\ShipmentItemInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class ShipmentItemRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ShipmentItemRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(ShipmentItemRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/shipment_items_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(ShipmentItemInterface::NAME) + ->setValue('item 2') + ->create(); + $filter2 = $filterBuilder->setField(ShipmentItemInterface::NAME) + ->setValue('item 3') + ->create(); + $filter3 = $filterBuilder->setField(ShipmentItemInterface::NAME) + ->setValue('item 4') + ->create(); + $filter4 = $filterBuilder->setField(ShipmentItemInterface::NAME) + ->setValue('item 5') + ->create(); + $filter5 = $filterBuilder->setField(ShipmentItemInterface::PRICE) + ->setValue(45) + ->setConditionType('lt') + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(ShipmentItemInterface::NAME) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('item 2', $items[0][ShipmentItemInterface::NAME]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentTrackRepositoryInterfaceTest.php b/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentTrackRepositoryInterfaceTest.php new file mode 100644 index 00000000000..dcbba427073 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Api/ShipmentTrackRepositoryInterfaceTest.php @@ -0,0 +1,82 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Sales\Api\Data\ShipmentTrackInterface; +use Magento\TestFramework\Helper\Bootstrap; + +class ShipmentTrackRepositoryInterfaceTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ShipmentTrackRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(ShipmentTrackRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Sales/_files/shipment_tracks_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField(ShipmentTrackInterface::TITLE) + ->setValue('title 2') + ->create(); + $filter2 = $filterBuilder->setField(ShipmentTrackInterface::DESCRIPTION) + ->setValue('description 3') + ->create(); + $filter3 = $filterBuilder->setField(ShipmentTrackInterface::TRACK_NUMBER) + ->setValue('track number 4') + ->create(); + $filter4 = $filterBuilder->setField(ShipmentTrackInterface::CARRIER_CODE) + ->setValue('carrier code 5') + ->create(); + $filter5 = $filterBuilder->setField(ShipmentTrackInterface::QTY) + ->setConditionType('lt') + ->setValue(5) + ->create(); + $filter6 = $filterBuilder->setField(ShipmentTrackInterface::WEIGHT) + ->setValue(1) + ->create(); + + /**@var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(ShipmentTrackInterface::DESCRIPTION) + ->setDirection(SortOrder::SORT_DESC) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3, $filter4]); + $searchCriteriaBuilder->addFilters([$filter5]); + $searchCriteriaBuilder->addFilters([$filter6]); + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('title 2', $items[0][ShipmentTrackInterface::TITLE]); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_comments_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_comments_for_search.php new file mode 100644 index 00000000000..1b948727929 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_comments_for_search.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Creditmemo; +use Magento\Sales\Model\Order\Creditmemo\Comment; +use Magento\Sales\Model\Order\CreditmemoFactory; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +/** @var Order $order */ +$order = Bootstrap::getObjectManager()->create(Order::class); +$order->loadByIncrementId('100000001'); + +/** @var CreditmemoFactory $creditmemoFactory */ +$creditmemoFactory = Bootstrap::getObjectManager()->get(CreditmemoFactory::class); + +/** @var Creditmemo $creditmemo */ +$creditmemo = $creditmemoFactory->createByOrder($order, $order->getData()); +$creditmemo->setOrder($order); +$creditmemo->setState(Creditmemo::STATE_OPEN); +$creditmemo->setIncrementId('100000001'); +$creditmemo->save(); + +$comments = [ + [ + 'comment' => 'comment 1', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 2', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 3', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 4', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 5', + 'is_visible_on_front' => 0, + 'is_customer_notified' => 1, + ], +]; + +foreach ($comments as $data) { + /** @var $comment Comment */ + $comment = Bootstrap::getObjectManager()->create(Comment::class); + $comment->setParentId($creditmemo->getId()); + $comment->setComment($data['comment']); + $comment->setIsVisibleOnFront($data['is_visible_on_front']); + $comment->setIsCustomerNotified($data['is_customer_notified']); + $comment->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_items_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_items_for_search.php new file mode 100644 index 00000000000..2fd9b45f986 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_items_for_search.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Creditmemo; +use Magento\Sales\Model\Order\Creditmemo\Item; +use Magento\Sales\Model\Order\Creditmemo\ItemFactory; +use Magento\Sales\Model\Order\CreditmemoFactory; +use Magento\Sales\Model\Order\Item as OrderItem; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +$orderCollection = Bootstrap::getObjectManager()->create(Order::class)->getCollection(); +/** @var \Magento\Sales\Model\Order $order */ +$order = $orderCollection->getFirstItem(); + +/** @var ItemFactory $creditmemoItemFactory */ +$creditmemoItemFactory = Bootstrap::getObjectManager()->create(ItemFactory::class); +/** @var CreditmemoFactory $creditmemoFactory */ +$creditmemoFactory = Bootstrap::getObjectManager()->get(CreditmemoFactory::class); +/** @var Creditmemo $creditmemo */ +$creditmemo = $creditmemoFactory->createByOrder($order, $order->getData()); +$creditmemo->setOrder($order); +$creditmemo->setState(Creditmemo::STATE_OPEN); +$creditmemo->save(); + +$items = [ + [ + 'name' => 'item 1', + 'base_price' => 10, + 'price' => 10, + 'row_total' => 10, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 2', + 'base_price' => 20, + 'price' => 20, + 'row_total' => 20, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 3', + 'base_price' => 30, + 'price' => 30, + 'row_total' => 30, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 4', + 'base_price' => 40, + 'price' => 40, + 'row_total' => 40, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 5', + 'base_price' => 50, + 'price' => 50, + 'row_total' => 50, + 'product_type' => 'simple', + 'qty' => 2, + 'qty_invoiced' => 20, + 'qty_refunded' => 2, + ], +]; + +foreach ($items as $data) { + /** @var OrderItem $orderItem */ + $orderItem = $objectManager->create(OrderItem::class); + $orderItem->setProductId($product->getId())->setQtyOrdered(10); + $orderItem->setBasePrice($data['base_price']); + $orderItem->setPrice($data['price']); + $orderItem->setRowTotal($data['row_total']); + $orderItem->setProductType($data['product_type']); + $orderItem->setQtyRefunded(1); + $orderItem->setQtyInvoiced(10); + $orderItem->setOriginalPrice(20); + + $order->addItem($orderItem); + $order->save(); + + /** @var Item $creditmemoItem */ + $creditmemoItem = $creditmemoItemFactory->create(); + $creditmemoItem->setCreditmemo($creditmemo) + ->setName($data['name']) + ->setOrderItemId($orderItem->getItemId()) + ->setQty($data['qty']) + ->setPrice($data['price']) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_comments_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_comments_for_search.php new file mode 100644 index 00000000000..bc10027fb35 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_comments_for_search.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\DB\Transaction; +use Magento\Sales\Api\InvoiceManagementInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Invoice; +use Magento\Sales\Model\Order\Invoice\Comment; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +/** @var InvoiceManagementInterface $orderService */ +$orderService = Bootstrap::getObjectManager()->create(InvoiceManagementInterface::class); +/** @var Invoice $invoice */ +$invoice = $orderService->prepareInvoice($order); +$invoice->register(); +/** @var Order $order */ +$order = $invoice->getOrder(); +$order->setIsInProcess(true); +/** @var Transaction $transactionSave */ +$transactionSave = Bootstrap::getObjectManager()->create(Transaction::class); +$transactionSave->addObject($invoice)->addObject($order)->save(); + +$comments = [ + [ + 'comment' => 'comment 1', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 2', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 3', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 4', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 5', + 'is_visible_on_front' => 0, + 'is_customer_notified' => 1, + ], +]; + +foreach ($comments as $data) { + /** @var $comment Comment */ + $comment = Bootstrap::getObjectManager()->create(Comment::class); + $comment->setParentId($invoice->getId()); + $comment->setComment($data['comment']); + $comment->setIsVisibleOnFront($data['is_visible_on_front']); + $comment->setIsCustomerNotified($data['is_customer_notified']); + $comment->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_items_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_items_for_search.php new file mode 100644 index 00000000000..737baec6cb6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_items_for_search.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\DB\Transaction; +use Magento\Sales\Api\InvoiceManagementInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Invoice; +use Magento\Sales\Model\Order\Invoice\Item; +use Magento\Sales\Model\Order\Invoice\ItemFactory; +use Magento\Sales\Model\Order\InvoiceFactory; +use Magento\Sales\Model\Order\Item as OrderItem; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +/** @var InvoiceManagementInterface $orderService */ +$orderService = Bootstrap::getObjectManager()->create(InvoiceManagementInterface::class); +/** @var Invoice $invoice */ +$invoice = $orderService->prepareInvoice($order); +$invoice->register(); +/** @var Order $order */ +$order = $invoice->getOrder(); +$order->setIsInProcess(true); +/** @var Transaction $transactionSave */ +$transactionSave = Bootstrap::getObjectManager()->create(Transaction::class); +$transactionSave->addObject($invoice)->addObject($order)->save(); + +/** @var ItemFactory $invoiceItemFactory */ +$invoiceItemFactory = Bootstrap::getObjectManager()->create(ItemFactory::class); + +$items = [ + [ + 'name' => 'item 1', + 'base_price' => 10, + 'price' => 10, + 'row_total' => 10, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 2', + 'base_price' => 20, + 'price' => 20, + 'row_total' => 20, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 3', + 'base_price' => 30, + 'price' => 30, + 'row_total' => 30, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 4', + 'base_price' => 40, + 'price' => 40, + 'row_total' => 40, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 5', + 'base_price' => 50, + 'price' => 50, + 'row_total' => 50, + 'product_type' => 'simple', + 'qty' => 2, + 'qty_invoiced' => 20, + 'qty_refunded' => 2, + ], +]; + +foreach ($items as $data) { + /** @var OrderItem $orderItem */ + $orderItem = $objectManager->create(OrderItem::class); + $orderItem->setProductId($product->getId())->setQtyOrdered(10); + $orderItem->setBasePrice($data['base_price']); + $orderItem->setPrice($data['price']); + $orderItem->setRowTotal($data['row_total']); + $orderItem->setProductType($data['product_type']); + $orderItem->setQtyRefunded(1); + $orderItem->setQtyInvoiced(10); + $orderItem->setOriginalPrice(20); + + $order->addItem($orderItem); + $order->save(); + + /** @var Item $invoiceItem */ + $invoiceItem = $invoiceItemFactory->create(); + $invoiceItem->setInvoice($invoice) + ->setName($data['name']) + ->setOrderItemId($orderItem->getItemId()) + ->setQty($data['qty']) + ->setPrice($data['price']) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_status_history_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_status_history_for_search.php new file mode 100644 index 00000000000..32d63edda16 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_status_history_for_search.php @@ -0,0 +1,49 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order\Status\History; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +$comments = [ + [ + 'comment' => 'comment 1', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 2', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 3', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 4', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 5', + 'is_visible_on_front' => 0, + 'is_customer_notified' => 1, + ], +]; + +foreach ($comments as $data) { + /** @var $comment History */ + $comment = Bootstrap::getObjectManager()->create(History::class); + $comment->setParentId($order->getId()); + $comment->setComment($data['comment']); + $comment->setIsVisibleOnFront($data['is_visible_on_front']); + $comment->setIsCustomerNotified($data['is_customer_notified']); + $comment->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_comments_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_comments_for_search.php new file mode 100644 index 00000000000..a588d7b5acc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_comments_for_search.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Payment\Helper\Data; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Shipment; +use Magento\Sales\Model\Order\Shipment\Comment; +use Magento\Sales\Model\Order\Shipment\Item; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +/** @var Order $order */ +$payment = $order->getPayment(); +$paymentInfoBlock = Bootstrap::getObjectManager()->get(Data::class) + ->getInfoBlock($payment); +$payment->setBlockMock($paymentInfoBlock); + +/** @var Shipment $shipment */ +$shipment = Bootstrap::getObjectManager()->create(Shipment::class); +$shipment->setOrder($order); + +/** @var Item $shipmentItem */ +$shipmentItem = Bootstrap::getObjectManager()->create(Item::class); +$shipmentItem->setOrderItem($orderItem); +$shipment->addItem($shipmentItem); +$shipment->setPackages([['1'], ['2']]); +$shipment->setShipmentStatus(\Magento\Sales\Model\Order\Shipment::STATUS_NEW); +$shipment->save(); + +$comments = [ + [ + 'comment' => 'comment 1', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 2', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 3', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 4', + 'is_visible_on_front' => 1, + 'is_customer_notified' => 1, + ], + [ + 'comment' => 'comment 5', + 'is_visible_on_front' => 0, + 'is_customer_notified' => 1, + ], +]; + +foreach ($comments as $data) { + /** @var $comment Comment */ + $comment = Bootstrap::getObjectManager()->create(Comment::class); + $comment->setParentId($shipment->getId()); + $comment->setComment($data['comment']); + $comment->setIsVisibleOnFront($data['is_visible_on_front']); + $comment->setIsCustomerNotified($data['is_customer_notified']); + $comment->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_items_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_items_for_search.php new file mode 100644 index 00000000000..a61db84eeb6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_items_for_search.php @@ -0,0 +1,116 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Payment\Helper\Data; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Shipment; +use Magento\Sales\Model\Order\Shipment\Item; +use Magento\Sales\Model\Order\Shipment\ItemFactory; +use Magento\Sales\Model\Order\Item as OrderItem; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +/** @var Order $order */ +$payment = $order->getPayment(); +$paymentInfoBlock = Bootstrap::getObjectManager()->get(Data::class) + ->getInfoBlock($payment); +$payment->setBlockMock($paymentInfoBlock); + +/** @var Shipment $shipment */ +$shipment = Bootstrap::getObjectManager()->create(Shipment::class); +$shipment->setOrder($order); + +/** @var Item $shipmentItem */ +$shipmentItem = Bootstrap::getObjectManager()->create(Item::class); +$shipmentItem->setOrderItem($orderItem); +$shipment->addItem($shipmentItem); +$shipment->setPackages([['1'], ['2']]); +$shipment->setShipmentStatus(\Magento\Sales\Model\Order\Shipment::STATUS_NEW); +$shipment->save(); + +/** @var ItemFactory $shipmentItemFactory */ +$shipmentItemFactory = Bootstrap::getObjectManager()->create(ItemFactory::class); + +$items = [ + [ + 'name' => 'item 1', + 'base_price' => 10, + 'price' => 10, + 'row_total' => 10, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 2', + 'base_price' => 20, + 'price' => 20, + 'row_total' => 20, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 3', + 'base_price' => 30, + 'price' => 30, + 'row_total' => 30, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 4', + 'base_price' => 40, + 'price' => 40, + 'row_total' => 40, + 'product_type' => 'simple', + 'qty' => 10, + 'qty_invoiced' => 10, + 'qty_refunded' => 1, + ], + [ + 'name' => 'item 5', + 'base_price' => 50, + 'price' => 50, + 'row_total' => 50, + 'product_type' => 'simple', + 'qty' => 2, + 'qty_invoiced' => 20, + 'qty_refunded' => 2, + ], +]; + +foreach ($items as $data) { + /** @var OrderItem $orderItem */ + $orderItem = $objectManager->create(OrderItem::class); + $orderItem->setProductId($product->getId())->setQtyOrdered(10); + $orderItem->setBasePrice($data['base_price']); + $orderItem->setPrice($data['price']); + $orderItem->setRowTotal($data['row_total']); + $orderItem->setProductType($data['product_type']); + $orderItem->setQtyOrdered(100); + $orderItem->setQtyInvoiced(10); + $orderItem->setOriginalPrice(20); + + $order->addItem($orderItem); + $order->save(); + + /** @var Item $shipmentItem */ + $shipmentItem = $shipmentItemFactory->create(); + $shipmentItem->setShipment($shipment) + ->setName($data['name']) + ->setOrderItem($orderItem) + ->setOrderItemId($orderItem->getItemId()) + ->setQty($data['qty']) + ->setPrice($data['price']) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_tracks_for_search.php b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_tracks_for_search.php new file mode 100644 index 00000000000..200b1009daa --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_tracks_for_search.php @@ -0,0 +1,90 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Payment\Helper\Data; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Shipment; +use Magento\Sales\Model\Order\Shipment\Track; +use Magento\Sales\Model\Order\Shipment\Item; +use Magento\TestFramework\Helper\Bootstrap; + +require 'default_rollback.php'; +require __DIR__ . '/order.php'; + +/** @var Order $order */ +$payment = $order->getPayment(); +$paymentInfoBlock = Bootstrap::getObjectManager()->get(Data::class) + ->getInfoBlock($payment); +$payment->setBlockMock($paymentInfoBlock); + +/** @var Shipment $shipment */ +$shipment = Bootstrap::getObjectManager()->create(Shipment::class); +$shipment->setOrder($order); + +/** @var Item $shipmentItem */ +$shipmentItem = Bootstrap::getObjectManager()->create(Item::class); +$shipmentItem->setOrderItem($orderItem); +$shipment->addItem($shipmentItem); +$shipment->setPackages([['1'], ['2']]); +$shipment->setShipmentStatus(\Magento\Sales\Model\Order\Shipment::STATUS_NEW); +$shipment->save(); + +$tracks = [ + [ + 'title' => 'title 1', + 'carrier_code' => 'carrier code 1', + 'track_number' => 'track number 1', + 'description' => 'description 1', + 'qty' => 1, + 'weight' => 1, + ], + [ + 'title' => 'title 2', + 'carrier_code' => 'carrier code 2', + 'track_number' => 'track number 2', + 'description' => 'description 2', + 'qty' => 2, + 'weight' => 1, + ], + [ + 'title' => 'title 3', + 'carrier_code' => 'carrier code 3', + 'track_number' => 'track number 3', + 'description' => 'description 3', + 'qty' => 3, + 'weight' => 1, + ], + [ + 'title' => 'title 4', + 'carrier_code' => 'carrier code 4', + 'track_number' => 'track number 4', + 'description' => 'description 4', + 'qty' => 4, + 'weight' => 1, + ], + [ + 'title' => 'title 5', + 'carrier_code' => 'carrier code 5', + 'track_number' => 'track number 5', + 'description' => 'description 5', + 'qty' => 5, + 'weight' => 2, + ], +]; + +foreach ($tracks as $data) { + /** @var $track Track */ + $track = Bootstrap::getObjectManager()->create(Track::class); + $track->setOrderId($order->getId()); + $track->setParentId($shipment->getId()); + $track->setTitle($data['title']); + $track->setCarrierCode($data['carrier_code']); + $track->setTrackNumber($data['track_number']); + $track->setDescription($data['description']); + $track->setQty($data['qty']); + $track->setWeight($data['weight']); + $track->save(); +} -- GitLab From 334c1da106175637f1195f0b299aebe6d37041bd Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Thu, 4 Aug 2016 17:25:15 +0300 Subject: [PATCH 151/838] MAGETWO-55364: [WCAG 2.0 AA] Add Aria-Labels for Color Swatches - Fix JS DOC text --- .../Swatches/view/frontend/web/js/swatch-renderer.js | 4 ++-- lib/web/mage/validation.js | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 75fb9c73264..c4d16c95328 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -18,9 +18,9 @@ define([ */ $.widget('mage.validation', $.mage.validation, { /** - * Handle form with swatches validation + * Handle form with swatches validation. Focus on first invalid swatch block. * - * @param {Object} event + * @param {jQuery.Event} event * @param {Object} validation */ listenFormValidateHandler: function (event, validation) { diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 79ac8f42fee..b3044ce303d 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1515,6 +1515,7 @@ this.validate.resetForm(); } }, + /** * Validation creation * @protected @@ -1531,6 +1532,7 @@ this._listenFormValidate(); }, + /** * Validation listening * @protected @@ -1538,10 +1540,11 @@ _listenFormValidate: function () { $('form').on('invalid-form.validate', this.listenFormValidateHandler); }, + /** - * Handle form validation + * Handle form validation. Focus on first invalid form field. * - * @param {Object} event + * @param {jQuery.Event} event * @param {Object} validation */ listenFormValidateHandler: function (event, validation) { @@ -1565,6 +1568,7 @@ .removeAttr('aria-invalid'); }); } + if (firstActive.length) { firstActive.focus(); } -- GitLab From 7dbe78bbd4e9e1937b1c96ff6c3ed5f27a2bc341 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Thu, 4 Aug 2016 18:11:00 +0300 Subject: [PATCH 152/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - refactoring to UnderscoreJS methods --- app/code/Magento/Ui/view/base/web/js/form/form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js index 9e6ed07a96f..2431d19cf9d 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -266,7 +266,7 @@ define([ focusInvalid: function () { var invalidField = _.find(this.delegate('isInvalid')); - if (typeof invalidField !== 'undefined' && typeof invalidField.focused === 'function') { + if (!_.isUndefined(invalidField) && _.isFunction(invalidField.focused)) { invalidField.focused(true); } -- GitLab From 52158a04fd0f1d0f96bf35eeff7ac79c9f5121e3 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 4 Aug 2016 18:19:01 +0300 Subject: [PATCH 153/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../testsuite/Magento/Vault/_files/payment_tokens.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php index 7185d224e33..e021dc7d437 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -include "customer.php"; +include "customer.php"; use Magento\Customer\Model\Customer; use Magento\Vault\Model\PaymentToken; -- GitLab From 7928ca632853be463f8ca043b20c97e047de789c Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 10:12:49 -0500 Subject: [PATCH 154/838] MAGETWO-55925: Eliminate @escapeNotVerified in CatalogWidget Module Applying escape functions in templates --- .../templates/product/widget/conditions.phtml | 17 +++++---- .../product/widget/content/grid.phtml | 37 ++++++++----------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml index df63335ed3c..8ecc05e0d00 100644 --- a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml +++ b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml @@ -6,15 +6,16 @@ // @codingStandardsIgnoreFile -?> -<?php +/** @var \Magento\CatalogWidget\Block\Product\Widget\Conditions $block */ + $element = $block->getElement(); -$fieldId = ($element->getHtmlContainerId()) ? ' id="' . $element->getHtmlContainerId() . '"' : ''; -$fieldClass = "field admin__field field-{$element->getId()} {$element->getCssClass()}"; -$fieldClass .= ($element->getRequired()) ? ' required' : ''; -$fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' . $block->getUiId('form-field', $element->getId()); +$fieldId = $element->getHtmlContainerId() ? ' id="' . $block->escapeHtmlAttr($element->getHtmlContainerId()) . '"' : ''; +$fieldClass = 'field admin__field field-' . $block->escapeHtmlAttr($element->getId()) . ' ' + . $block->escapeHtmlAttr($element->getCssClass()); +$fieldClass .= $element->getRequired() ? ' required' : ''; +$fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' + . $block->getUiId('form-field', $block->escapeHtmlAttr($element->getId())); ?> - <div<?php /* @escapeNotVerified */ echo $fieldAttributes ?>> <?php echo $element->getLabelHtml() ?> <div class="control admin__field-control"> @@ -32,6 +33,6 @@ $fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' . $block->getUiId( "Magento_Rule/rules", "prototype" ], function(VarienRulesForm){ - window.<?php echo $block->getHtmlId() ?> = new VarienRulesForm('<?php echo $block->getHtmlId() ?>', '<?php /* @escapeNotVerified */ echo $block->getNewChildUrl() ?>'); + window.<?php echo $block->getHtmlId() ?> = new VarienRulesForm('<?php echo $block->getHtmlId() ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); }); </script> diff --git a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml index 13be83f1493..6c1e4715369 100644 --- a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml +++ b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml @@ -6,15 +6,9 @@ // @codingStandardsIgnoreFile +/** @var \Magento\CatalogWidget\Block\Product\ProductsList $block */ ?> -<?php -/** - * Template for displaying products list widget - * - * @var $block \Magento\CatalogWidget\Block\Product\ProductsList - */ -?> -<?php if ($exist = ($block->getProductCollection() && $block->getProductCollection()->getSize())):?> +<?php if ($exist = ($block->getProductCollection() && $block->getProductCollection()->getSize())): ?> <?php $type = 'widget-product-grid'; @@ -30,27 +24,28 @@ $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::DEFAULT_VIEW; $description = false; ?> - <div class="block widget block-products-list <?php /* @escapeNotVerified */ echo $mode; ?>"> - <?php if ($title):?> + <div class="block widget block-products-list <?php /* @noEscape */ echo $mode; ?>"> + <?php if ($title): ?> <div class="block-title"> - <strong><?php /* @escapeNotVerified */ echo $title; ?></strong> + <strong><?php /* @noEscape */ echo $title; ?></strong> </div> <?php endif ?> <div class="block-content"> - <?php /* @escapeNotVerified */ echo '<!-- ' . $image . '-->' ?> - <div class="products-<?php /* @escapeNotVerified */ echo $mode; ?> <?php /* @escapeNotVerified */ echo $mode; ?>"> - <ol class="product-items <?php /* @escapeNotVerified */ echo $type; ?>"> + <?php /* @noEscape */ echo '<!-- ' . $image . '-->' ?> + <div class="products-<?php /* @noEscape */ echo $mode; ?> <?php /* @noEscape */ echo $mode; ?>"> + <ol class="product-items <?php /* @noEscape */ echo $type; ?>"> <?php $iterator = 1; ?> <?php foreach ($items as $_item): ?> - <?php /* @escapeNotVerified */ echo($iterator++ == 1) ? '<li class="product-item">' : '</li><li class="product-item">' ?> + <?php if ($iterator++ != 1): ?></li><?php endif ?> + <li class="product-item"> <div class="product-item-info"> - <a href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($_item) ?>" class="product-item-photo"> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($_item)) ?>" class="product-item-photo"> <?php echo $block->getImage($_item, $image)->toHtml(); ?> </a> <div class="product-item-details"> <strong class="product-item-name"> <a title="<?php echo $block->escapeHtml($_item->getName()) ?>" - href="<?php /* @escapeNotVerified */ echo $block->getProductUrl($_item) ?>" + href="<?php echo $block->escapeUrl($block->getProductUrl($_item)) ?>" class="product-item-link"> <?php echo $block->escapeHtml($_item->getName()) ?> </a> @@ -70,7 +65,7 @@ <?php if ($_item->isSaleable()): ?> <?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)): ?> <button class="action tocart primary" - data-mage-init='{"redirectUrl":{"url":"<?php /* @escapeNotVerified */ echo $block->getAddToCartUrl($_item) ?>"}}' + data-mage-init='{"redirectUrl":{"url":"<?php echo $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>"> <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> @@ -80,7 +75,7 @@ $postData = $postDataHelper->getPostData($block->getAddToCartUrl($_item), ['product' => $_item->getEntityId()]) ?> <button class="action tocart primary" - data-post='<?php /* @escapeNotVerified */ echo $postData; ?>' + data-post='<?php /* @noEscape */ echo $postData; ?>' type="button" title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>"> <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> @@ -98,7 +93,7 @@ <div class="actions-secondary" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow() && $showWishlist): ?> <a href="#" - data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($_item); ?>' + data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($_item); ?>' class="action towishlist" data-action="add-to-wishlist" title="<?php /* @escapeNotVerified */ echo __('Add to Wish List') ?>"> <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> @@ -107,7 +102,7 @@ <?php if ($block->getAddToCompareUrl() && $showCompare): ?> <?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');?> <a href="#" class="action tocompare" - data-post='<?php /* @escapeNotVerified */ echo $compareHelper->getPostDataParams($_item);?>' + data-post='<?php /* @noEscape */ echo $compareHelper->getPostDataParams($_item);?>' title="<?php /* @escapeNotVerified */ echo __('Add to Compare') ?>"> <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span> </a> -- GitLab From 41df89ad1883722c502580e9f09249c972f75d21 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 10:32:33 -0500 Subject: [PATCH 155/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../Magento/Customer/view/frontend/templates/address/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index dc08ef9df17..59093d0f309 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -213,7 +213,7 @@ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeHtmlAttr($block->getRegionId()) ?>", + "defaultRegion": "<?php echo $block->escapeJs($block->getRegionId()) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } -- GitLab From cf726434828507d6de65ec0e985eb5c45b1b8afc Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 10:49:47 -0500 Subject: [PATCH 156/838] MAGETWO-55927: Eliminate @escapeNotVerified in UrlRewrite Module Applying escape functions in templates --- app/code/Magento/UrlRewrite/Block/Selector.php | 11 +++++++++++ .../view/adminhtml/templates/categories.phtml | 14 +++++++------- .../UrlRewrite/view/adminhtml/templates/edit.phtml | 9 ++------- .../view/adminhtml/templates/selector.phtml | 7 +++---- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/UrlRewrite/Block/Selector.php b/app/code/Magento/UrlRewrite/Block/Selector.php index 85ec1ea46e7..90ec4a6a688 100644 --- a/app/code/Magento/UrlRewrite/Block/Selector.php +++ b/app/code/Magento/UrlRewrite/Block/Selector.php @@ -76,4 +76,15 @@ class Selector extends \Magento\Backend\Block\Template $keys = array_keys($this->_modes); return array_shift($keys); } + + /** + * Get mode Url + * + * @param string $mode + * @return string + */ + public function getModeUrl($mode) + { + return $this->getUrl('adminhtml/*/*') . $mode; + } } diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml index 84a070e2cd2..6b464048873 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml @@ -6,21 +6,21 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\UrlRewrite\Block\Catalog\Category\Tree */ +/** @var \Magento\UrlRewrite\Block\Catalog\Category\Tree $block */ ?> <fieldset class="admin__fieldset" data-ui-id="category-selector"> <legend class="admin__legend"><span><?php /* @escapeNotVerified */ echo __('Select Category') ?></span></legend> <div class="content content-category-tree"> <input type="hidden" name="categories" id="product_categories" value="" /> <?php if ($block->getRoot()): ?> - <div data-mage-init="<?php - echo $block->escapeHtml($this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode([ + <div data-mage-init="<?php /* noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( + [ 'categoryTree' => [ - 'data' => $block->getTreeArray(null), - 'url' => $block->getLoadTreeUrl(), + 'data' => $block->getTreeArray(), + 'url' => $block->escapeUrl($block->getLoadTreeUrl()), ], - ])); - ?>" class="jstree-default"></div> + ] + ); ?>" class="jstree-default"></div> <?php endif; ?> </div> </fieldset> diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml index 150b6fc6075..1ab8cf9191e 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/edit.phtml @@ -6,12 +6,9 @@ // @codingStandardsIgnoreFile -/** - * @var $block \Magento\UrlRewrite\Block\Edit - */ +/** @var \Magento\UrlRewrite\Block\Edit $block */ ?> <?php echo $block->getChildHtml() ?> - <?php if ($block->getChildBlock('form')): ?> <script> require([ @@ -19,10 +16,8 @@ require([ 'mage/backend/form', 'mage/backend/validation' ], function($){ - $('#edit_form').form() - .validation({validationUrl: '<?php /* @escapeNotVerified */ echo $block->getValidationUrl() ?>'}); - + .validation({validationUrl: '<?php echo $block->escapeUrl($block->getValidationUrl()) ?>'}); }); </script> <?php endif; ?> diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml index bdde86bc666..fa32232c4c7 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/selector.phtml @@ -6,19 +6,18 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\UrlRewrite\Block\Selector */ +/** @var \Magento\UrlRewrite\Block\Selector $block */ ?> <div class="form-inline"> <fieldset class="admin__fieldset fieldset" data-container-for="entity-type-selector"> <div class="admin__field field field-entity-type-selector"> <label for="entity-type-selector" class="admin__field-label label"> - <span><?php /* @escapeNotVerified */ echo $block->getSelectorLabel() ?></span> + <span><?php echo $block->escapeHtml($block->getSelectorLabel()) ?></span> </label> <div class="admin__field-control control"> - <?php $url = $this->helper('Magento\Backend\Helper\Data')->getUrl('adminhtml/*/*')?> <select data-role="entity-type-selector" class="admin__control-select select" onchange="window.location = this.value;" id="entity-type-selector"> <?php foreach ($block->getModes() as $mode => $label): ?> - <option <?php echo($block->isMode($mode) ? 'selected="selected" ' : '') ?>value="<?php /* @escapeNotVerified */ echo $url . $mode ?>"><?php /* @escapeNotVerified */ echo $label ?></option> + <option <?php /* noEscape */ echo $block->isMode($mode) ? 'selected="selected" ' : '' ?>value="<?php echo $block->escapeUrl($block->getModeUrl($mode)) ?>"><?php echo $block->escapeHtml($label) ?></option> <?php endforeach; ?> </select> </div> -- GitLab From 3838ffa117995087fbff55c49547f89caef6f359 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Thu, 4 Aug 2016 18:55:19 +0300 Subject: [PATCH 157/838] MAGETWO-55271: Cover with Functional Tests --- .../Test/Block/Extension/AbstractGrid.php | 45 ++++++++ .../Setup/Test/Block/Extension/Grid.php | 19 ++- .../Test/Block/Extension/InstallGrid.php | 47 +------- .../Setup/Test/Block/Extension/UpdateGrid.php | 41 +++++++ .../AssertMultipleUpdateSuccessMessage.php | 24 ++++ .../AssertSelectSeveralExtensions.php | 6 +- .../Setup/Test/Page/Adminhtml/SetupWizard.xml | 1 + .../Setup/Test/Repository/Extension.xml | 4 + .../Test/TestCase/AbstractExtensionTest.php | 44 +++++++ .../TestCase/ExtensionMultipleUpdateTest.php | 108 ++++++++++++++++++ .../TestCase/ExtensionMultipleUpdateTest.xml | 22 ++++ setup/view/magento/setup/extension-grid.phtml | 2 +- .../magento/setup/update-extension-grid.phtml | 2 +- 13 files changed, 313 insertions(+), 52 deletions(-) create mode 100644 dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/UpdateGrid.php create mode 100644 dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php create mode 100644 dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php create mode 100644 dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/AbstractGrid.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/AbstractGrid.php index a71d23be952..24403ce94c5 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/AbstractGrid.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/AbstractGrid.php @@ -36,6 +36,13 @@ abstract class AbstractGrid extends Block */ protected $extensionName = "//*[contains(text(), '%s')]"; + /** + * Checkbox for select extension. + * + * @var string + */ + protected $extensionCheckbox = "//tr[td/*[contains(text(), '%s')]]//*[contains(@ng-checked, 'selectedExtension')]"; + /** * Find Extension on the grid by name. * @@ -85,4 +92,42 @@ abstract class AbstractGrid extends Block return false; } + + /** + * Select several extensions to install on grid. + * + * @param Extension[] $extensions + * @return Extension[] + */ + public function selectSeveralExtensions(array $extensions) + { + while (true) { + foreach ($extensions as $key => $extension) { + if ($this->isExtensionOnGrid($extension->getExtensionName())) { + $this->selectExtension($extension->getExtensionName()); + unset($extensions[$key]); + } + } + + if (empty($extensions) || !$this->clickNextPageButton()) { + break; + } + } + + return $extensions; + } + + /** + * Select extension on grid, check checkbox. + * + * @param string $extensionName + * @return void + */ + protected function selectExtension($extensionName) + { + $this->_rootElement->find( + sprintf($this->extensionCheckbox, $extensionName), + Locator::SELECTOR_XPATH + )->click(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php index bfa6ed4ca9a..3e1378f942d 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php @@ -21,6 +21,13 @@ class Grid extends AbstractGrid */ protected $installButton = "//button[contains(@class, 'goInstall')]"; + /** + * 'Review Updates' button that opens grid with extensions for update. + * + * @var string + */ + protected $updateButton = "//button[contains(@class, 'goUpdate')]"; + /** * Select action of extension on the grid. * @@ -80,6 +87,16 @@ class Grid extends AbstractGrid $this->_rootElement->find($this->installButton, Locator::SELECTOR_XPATH)->click(); } + /** + * Click 'Review Updates' button. + * + * @return void + */ + public function clickUpdateButton() + { + $this->_rootElement->find($this->updateButton, Locator::SELECTOR_XPATH)->click(); + } + /** * Click to uninstall button. * @@ -119,7 +136,7 @@ class Grid extends AbstractGrid * @param Extension $extension * @return void */ - public function clickUpdateButton(Extension $extension) + public function clickUpdateActionButton(Extension $extension) { $this->clickSelectActionButton($extension); $button = $this->_rootElement->find( diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/InstallGrid.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/InstallGrid.php index 710e14a1669..3a23f74de25 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/InstallGrid.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/InstallGrid.php @@ -16,7 +16,7 @@ class InstallGrid extends AbstractGrid { /** * "Install" button of extension. - * + * * @var string */ protected $extensionInstall = "//tr[td/*[contains(text(), '%s')]]//*[contains(@class, 'action-wrap')]//button"; @@ -28,13 +28,6 @@ class InstallGrid extends AbstractGrid */ protected $extensionSelectVersion = "//tr[td/*[contains(text(), '%s')]]//*[contains(@id, 'selectedVersion')]"; - /** - * Checkbox for select extension. - * - * @var string - */ - protected $extensionCheckbox = "//tr[td/*[contains(text(), '%s')]]//*[contains(@ng-checked, 'selectedExtension')]"; - /** * "Install All" button. * @@ -75,42 +68,4 @@ class InstallGrid extends AbstractGrid { $this->_rootElement->find($this->installAllButton, Locator::SELECTOR_CSS)->click(); } - - /** - * Select several extensions to install on grid. - * - * @param Extension[] $extensions - * @return Extension[] - */ - public function selectSeveralExtensions(array $extensions) - { - while (true) { - foreach ($extensions as $key => $extension) { - if ($this->isExtensionOnGrid($extension->getExtensionName())) { - $this->selectExtension($extension->getExtensionName()); - unset($extensions[$key]); - } - } - - if (empty($extensions) || !$this->clickNextPageButton()) { - break; - } - } - - return $extensions; - } - - /** - * Select extension on grid, check checkbox. - * - * @param string $extensionName - * @return void - */ - protected function selectExtension($extensionName) - { - $this->_rootElement->find( - sprintf($this->extensionCheckbox, $extensionName), - Locator::SELECTOR_XPATH - )->click(); - } } diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/UpdateGrid.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/UpdateGrid.php new file mode 100644 index 00000000000..035c1722a39 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/UpdateGrid.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Setup\Test\Block\Extension; + +use Magento\Mtf\Client\Locator; +use Magento\Setup\Test\Fixture\Extension; + +/** + * Class UpdateGrid + * + * Grid with extension updates. + */ +class UpdateGrid extends AbstractGrid +{ + /** + * 'Update All' button. + * + * @var string + */ + protected $updateAllButton = "[ng-click*='updateAll']"; + + /** + * Grid that contains the list of extensions. + * + * @var string + */ + protected $dataGrid = '#updateExtensionGrid'; + + /** + * Click to update all button. + * + * @return void + */ + public function clickUpdateAllButton() + { + $this->_rootElement->find($this->updateAllButton, Locator::SELECTOR_CSS)->click(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php new file mode 100644 index 00000000000..1286f8939f7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Setup\Test\Constraint\Extension; + +use Magento\Mtf\Constraint\AbstractConstraint; + +/** + * Class AssertMultipleUpdateSuccessMessage + */ +class AssertMultipleUpdateSuccessMessage extends AbstractConstraint +{ + public function processAssert() + { + + } + + public function toString() + { + // TODO: Implement toString() method. + } +} diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertSelectSeveralExtensions.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertSelectSeveralExtensions.php index 094ae150989..c186f9bf20c 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertSelectSeveralExtensions.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertSelectSeveralExtensions.php @@ -7,7 +7,7 @@ namespace Magento\Setup\Test\Constraint\Extension; use Magento\Mtf\Constraint\AbstractConstraint; -use Magento\Setup\Test\Block\Extension\InstallGrid; +use Magento\Setup\Test\Block\Extension\AbstractGrid; use Magento\Setup\Test\Fixture\Extension; /** @@ -18,11 +18,11 @@ class AssertSelectSeveralExtensions extends AbstractConstraint /** * Assert that extensions were selected on the grid. * - * @param InstallGrid $grid + * @param AbstractGrid $grid * @param Extension[] $extensions * @return void */ - public function processAssert(InstallGrid $grid, array $extensions) + public function processAssert(AbstractGrid $grid, array $extensions) { $extensions = $grid->selectSeveralExtensions($extensions); \PHPUnit_Framework_Assert::assertEmpty( diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Page/Adminhtml/SetupWizard.xml b/dev/tests/functional/tests/app/Magento/Setup/Test/Page/Adminhtml/SetupWizard.xml index 2e5ad0b1fdc..d8d6f828f2f 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Page/Adminhtml/SetupWizard.xml +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Page/Adminhtml/SetupWizard.xml @@ -21,5 +21,6 @@ <block name="successMessage" class="Magento\Setup\Test\Block\SuccessMessage" locator="body" strategy="css selector"/> <block name="moduleGrid" class="Magento\Setup\Test\Block\Module\Grid" locator=".admin__data-grid-outer-wrap" strategy="css selector"/> <block name="moduleStatus" class="Magento\Setup\Test\Block\Module\Status" locator="body" strategy="css selector"/> + <block name="extensionsUpdateGrid" class="Magento\Setup\Test\Block\Extension\UpdateGrid" locator="#main" strategy="css selector"/> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml b/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml index 2a015016a78..ae00a5b4dc7 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml @@ -15,10 +15,14 @@ <dataset name="firstExtension"> <field name="extensionName" xsi:type="string">magento/module-customer-sample-data</field> + <field name="version" xsi:type="string">100.1.0-rc3</field> + <field name="versionToUpdate" xsi:type="string">100.1.0</field> </dataset> <dataset name="secondExtension"> <field name="extensionName" xsi:type="string">magento/module-theme-sample-data</field> + <field name="version" xsi:type="string">100.1.0-rc3</field> + <field name="versionToUpdate" xsi:type="string">100.1.0</field> </dataset> </repository> </config> diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php index f1374d4ef73..bcc3b65c8d9 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php @@ -143,4 +143,48 @@ abstract class AbstractExtensionTest extends Injectable $this->fail('Extension is not uninstalled!'); } } + + /** + * @param Extension $extension + * @param BackupOptions $backupOptions + * @param AssertFindExtensionOnGrid $assertFindExtensionOnGrid + * @param AssertSuccessfulReadinessCheck $assertReadiness + * @param AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck + * @param AssertSuccessMessage $assertSuccessMessage + */ + protected function installExtension( + Extension $extension, + BackupOptions $backupOptions, + AssertFindExtensionOnGrid $assertFindExtensionOnGrid, + AssertSuccessfulReadinessCheck $assertReadiness, + AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck, + AssertSuccessMessage $assertSuccessMessage + ) { + // Open Extension Grid with extensions to install + $this->setupWizard->getSetupHome()->clickExtensionManager(); + $this->setupWizard->getExtensionsGrid()->waitLoader(); + $this->setupWizard->getExtensionsGrid()->clickInstallButton(); + + // Find extension on grid and install + $assertFindExtensionOnGrid->processAssert($this->setupWizard->getExtensionsInstallGrid(), $extension); + $this->setupWizard->getExtensionsInstallGrid()->install($extension); + + $this->readinessCheckAndBackup($assertReadiness, $backupOptions); + + // Install Extension + $assertExtensionAndVersionCheck->processAssert( + $this->setupWizard, + $extension, + AssertExtensionAndVersionCheck::TYPE_INSTALL + ); + $this->setupWizard->getUpdaterExtension()->clickStartButton(); + $assertSuccessMessage->processAssert( + $this->setupWizard, + $extension, + AssertSuccessMessage::TYPE_INSTALL + ); + + // Open Web Setup Wizard + $this->setupWizard->open(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php new file mode 100644 index 00000000000..44be6f7e958 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Setup\Test\TestCase; + +use Magento\Mtf\Fixture\FixtureFactory; +use Magento\Setup\Test\Constraint\AssertSuccessfulReadinessCheck; +use Magento\Setup\Test\Constraint\Extension\AssertExtensionAndVersionCheck; +use Magento\Setup\Test\Constraint\Extension\AssertFindExtensionOnGrid; +use Magento\Setup\Test\Constraint\Extension\AssertMultipleUpdateSuccessMessage; +use Magento\Setup\Test\Constraint\Extension\AssertSelectSeveralExtensions; +use Magento\Setup\Test\Constraint\Extension\AssertSuccessMessage; +use Magento\Setup\Test\Fixture\BackupOptions; +use Magento\Setup\Test\Fixture\Extension; +use Magento\Setup\Test\Fixture\RepoCredentials; + +/** + * @group Setup_(CS) + * @ZephyrId MAGETWO-56328, MAGETWO-56332 + */ +class ExtensionMultipleUpdateTest extends AbstractExtensionTest +{ + /** + * @param FixtureFactory $fixtureFactory + * @param RepoCredentials $repoCredentials + * @param BackupOptions $backupOptions + * @param AssertFindExtensionOnGrid $assertFindExtensionOnGrid + * @param AssertSuccessfulReadinessCheck $assertReadiness + * @param AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck + * @param AssertSuccessMessage $assertSuccessMessage + * @param AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage + * @param $needAuthentication + * @param array $extensions + */ + public function test( + FixtureFactory $fixtureFactory, + RepoCredentials $repoCredentials, + BackupOptions $backupOptions, + AssertFindExtensionOnGrid $assertFindExtensionOnGrid, + AssertSuccessfulReadinessCheck $assertReadiness, + AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck, + AssertSuccessMessage $assertSuccessMessage, + AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage, + $needAuthentication, + array $extensions + ) { + foreach ($extensions as $key => $options) { + $extensions[$key] = $fixtureFactory->create(Extension::class, $options); + } + + // Authenticate in admin area + $this->adminDashboard->open(); + + // Open Web Setup Wizard + $this->setupWizard->open(); + + // Authenticate on repo.magento.com + $this->repoAuthentication($needAuthentication, $repoCredentials); + + foreach ($extensions as $extension) { + $this->installExtension( + $extension, + $backupOptions, + $assertFindExtensionOnGrid, + $assertReadiness, + $assertExtensionAndVersionCheck, + $assertSuccessMessage + ); + } + + // Open Extension Grid with extensions to install + $this->setupWizard->getSetupHome()->clickExtensionManager(); + $this->setupWizard->getExtensionsGrid()->waitLoader(); + $this->setupWizard->getExtensionsGrid()->clickUpdateButton(); + + // Select several extensions on grid and check it + $this->setupWizard->getExtensionsUpdateGrid()->selectSeveralExtensions($extensions); + + // Click general "Update" button + $this->setupWizard->getExtensionsUpdateGrid()->clickUpdateAllButton(); + + $this->readinessCheckAndBackup($assertReadiness, $backupOptions); + + // Start installing + $this->setupWizard->getUpdaterExtension()->clickStartButton(); + + // Check success message + $assertMultipleUpdateSuccessMessage->processAssert( + $this->setupWizard, + $extensions, + AssertSuccessMessage::TYPE_INSTALL + ); + + // Uninstall installed extensions + foreach ($extensions as $extension) { + $this->uninstallExtension( + $extension, + $backupOptions, + $assertReadiness, + $assertFindExtensionOnGrid, + $assertExtensionAndVersionCheck, + $assertSuccessMessage + ); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml new file mode 100644 index 00000000000..dfe368f06d7 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Setup\Test\TestCase\ExtensionMultipleUpdateTest" summary="Multiple Update Extensions"> + <variation name="PerformMultipleUpdateExtensions"> + <data name="needAuthentication" xsi:type="boolean">false</data> + <data name="extensions" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">firstExtension</item> + </item> + <item name="1" xsi:type="array"> + <item name="dataset" xsi:type="string">secondExtension</item> + </item> + </data> + </variation> + </testCase> +</config> diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index 1b181c5bc9b..e309f020518 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -24,7 +24,7 @@ <div class="item-number">{{countOfUpdate}}</div> <div class="item-title">Updates<br />Available</div> <button ui-sref="root.update" href="#update-extension-grid" - ng-class="{'disabled' : !countOfUpdate}" + ng-class="{'disabled' : !countOfUpdate, 'goUpdate' : countOfUpdate}" type="button" class="btn"> Review Updates </button> diff --git a/setup/view/magento/setup/update-extension-grid.phtml b/setup/view/magento/setup/update-extension-grid.phtml index 2c8625a82ed..7dbe1e616af 100644 --- a/setup/view/magento/setup/update-extension-grid.phtml +++ b/setup/view/magento/setup/update-extension-grid.phtml @@ -13,7 +13,7 @@ </span> </div> </div> -<div class="admin__data-grid-outer-wrap"> +<div class="admin__data-grid-outer-wrap" id="updateExtensionGrid"> <div class="admin__data-grid-header"> <div class="admin__data-grid-header-row row row-gutter"> <div class="col-xs-3"> -- GitLab From ca5e890eaf7b9366d8a4da9d7d8e4bcfe98fbddd Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 11:02:55 -0500 Subject: [PATCH 158/838] MAGETWO-55925: Eliminate @escapeNotVerified in CatalogWidget Module Applying escape functions in templates --- .../view/adminhtml/templates/product/widget/conditions.phtml | 4 ++-- .../view/frontend/templates/product/widget/content/grid.phtml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml index 8ecc05e0d00..f5f2b898a97 100644 --- a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml +++ b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml @@ -16,7 +16,7 @@ $fieldClass .= $element->getRequired() ? ' required' : ''; $fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' . $block->getUiId('form-field', $block->escapeHtmlAttr($element->getId())); ?> -<div<?php /* @escapeNotVerified */ echo $fieldAttributes ?>> +<div<?php /* @noEscape */ echo $fieldAttributes ?>> <?php echo $element->getLabelHtml() ?> <div class="control admin__field-control"> <div class="rule-tree"> @@ -33,6 +33,6 @@ $fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' "Magento_Rule/rules", "prototype" ], function(VarienRulesForm){ - window.<?php echo $block->getHtmlId() ?> = new VarienRulesForm('<?php echo $block->getHtmlId() ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); + window.<?php echo $block->escapeJs($block->getHtmlId()) ?> = new VarienRulesForm('<?php echo $block->escapeJs($block->getHtmlId()) ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); }); </script> diff --git a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml index 6c1e4715369..080714bd228 100644 --- a/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml +++ b/app/code/Magento/CatalogWidget/view/frontend/templates/product/widget/content/grid.phtml @@ -27,7 +27,7 @@ <div class="block widget block-products-list <?php /* @noEscape */ echo $mode; ?>"> <?php if ($title): ?> <div class="block-title"> - <strong><?php /* @noEscape */ echo $title; ?></strong> + <strong><?php echo $block->escapeHtml($title); ?></strong> </div> <?php endif ?> <div class="block-content"> -- GitLab From fee4c475ace98046d4811ac1b10fae7cb736dc66 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 4 Aug 2016 11:46:11 -0500 Subject: [PATCH 159/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- lib/internal/Magento/Framework/View/Element/Html/Link.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/Html/Link.php b/lib/internal/Magento/Framework/View/Element/Html/Link.php index c5aba22bad7..c4e5460c7de 100644 --- a/lib/internal/Magento/Framework/View/Element/Html/Link.php +++ b/lib/internal/Magento/Framework/View/Element/Html/Link.php @@ -59,7 +59,7 @@ class Link extends \Magento\Framework\View\Element\Template foreach ($this->allowedAttributes as $attribute) { $value = $this->getDataUsingMethod($attribute); if ($value !== null) { - $attributes[$this->escapeHtml($attribute)] = $this->escapeHtml($value); + $attributes[$attribute] = $this->escapeHtml($value); } } -- GitLab From b6ce7ef847ed21300c5edbd73fd40f262b590f03 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 14:48:52 -0500 Subject: [PATCH 160/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../view/frontend/templates/widget/gender.phtml | 2 +- .../view/frontend/templates/widget/name.phtml | 15 +++++++-------- .../view/frontend/templates/widget/taxvat.phtml | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml index 58cd9a7b470..c05d7c7fef8 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml @@ -11,7 +11,7 @@ <div class="field gender<?php if ($block->isRequired()) echo ' required' ?>"> <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> <div class="control"> - <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?> <?php /* @noEscape */ echo $block->getFieldParams() ?>> + <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?>> <?php $options = $block->getGenderOptions(); ?> <?php $value = $block->getGender();?> <?php foreach ($options as $option):?> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index 336f89914b5..57dcdbb3085 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -19,7 +19,6 @@ For checkout/onepage/shipping.phtml: ->setObject($block->getAddress()) ->setFieldIdFormat('shipping:%s') ->setFieldNameFormat('shipping[%s]') - ->setFieldParams('onchange="shipping.setSameAsBilling(false);"') ->toHtml() ?> */ @@ -49,12 +48,12 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getPrefix()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?>> <?php else: ?> <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('prefix')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('prefix')) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('prefix')) ?>" - class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > + class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > <?php foreach ($block->getPrefixOptions() as $_option): ?> <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getPrefix() == $_option): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo __($_option) ?> @@ -75,7 +74,7 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('firstname')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getFirstname()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('firstname')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('firstname')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('firstname')) ?>" <?php if ($block->getAttributeValidationClass('firstname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> </div> </div> <?php if ($middle): ?> @@ -90,7 +89,7 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('middlename')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getMiddlename()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('middlename')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('middlename')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php echo $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('middlename')) ?>" <?php echo $isMiddlenameRequired ? ' data-validate="{required:true}"' : '' ?>> </div> </div> <?php endif; ?> @@ -104,7 +103,7 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('lastname')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getLastname()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('lastname')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('lastname')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('lastname')) ?>" <?php if ($block->getAttributeValidationClass('lastname') == 'required-entry') echo ' data-validate="{required:true}"' ?>> </div> </div> <?php if ($suffix): ?> @@ -119,12 +118,12 @@ $suffix = $block->showSuffix(); name="<?php echo $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getObject()->getSuffix()) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>" - class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> + class="input-text <?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php else: ?> <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('suffix')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('suffix')) ?>" title="<?php echo $block->escapeHtmlAttr($block->getStoreLabel('suffix')) ?>" - class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> + class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php foreach ($block->getSuffixOptions() as $_option): ?> <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getSuffix() == $_option): ?> selected="selected"<?php endif; ?>> <?php /* @escapeNotVerified */ echo __($_option) ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml index b0ae05d3886..0463d33ad6e 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml @@ -11,6 +11,6 @@ <div class="field taxvat<?php if ($block->isRequired()) echo ' required'; ?>"> <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> <div class="control"> - <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php /* @noEscape */ echo $block->getFieldParams() ?> <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> </div> </div> -- GitLab From ce5f076648238771c54be9e6b88ffed5f0cc3931 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 14:57:46 -0500 Subject: [PATCH 161/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- .../adminhtml/templates/rating/options.phtml | 29 +++++++++++++++++++ .../templates/rating/stars/detailed.phtml | 25 ++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml create mode 100644 app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml new file mode 100644 index 00000000000..b0712f11dec --- /dev/null +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +?> +<div class="entry-edit-head"> + <h4 class="icon-head head-edit-form fieldset-legend"><?php /* @escapeNotVerified */ echo __('Assigned Options') ?></h4> +</div> +<fieldset id="options_form"> +<?php if (!$options): ?> + <?php for ($_i = 1;$_i <= 5;$_i++): ?> + <span class="field-row"> + <label for="option_<?php /* @noEscape */ echo $_i ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <input id="option_<?php /* @noEscape */ echo $_i ?>" name="option[<?php /* @noEscape */ echo $_i ?>][code]" value="<?php /* @noEscape */ echo $_i ?>" class="input-text" type="text" /> + </span> + <?php endfor; ?> +<?php elseif ($options->getSize() > 0): ?> + <?php foreach ($options->getItems() as $_item): ?> + <span class="field-row"> + <label for="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <input id="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>" name="option[<?php echo $block->escapeHtmlAttr($_item->getId()) ?>][code]" value="<?php echo $block->escapeHtmlAttr($_item->getCode()) ?>" class="input-text" type="text" /> + </span> + <?php endforeach; ?> +<?php endif; ?> +</fieldset> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml new file mode 100644 index 00000000000..bdc65c0fbbf --- /dev/null +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +?> +<?php if ($block->getRating() && $block->getRating()->getSize()): ?> + <div class="ratings-container"> + <?php foreach ($block->getRating() as $_rating): ?> + <?php if ($_rating->getPercent()): ?> + <div class="ratings"> + <?php echo $block->escapeHtml($_rating->getRatingCode()) ?> + <div class="rating-box"> + <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getPercent()) ?>%;"></div> + </div> + </div> + <?php endif; ?> + <?php endforeach; ?> + </div> +<?php else: ?> + <?php /* @escapeNotVerified */ echo __("Rating isn't Available") ?> +<?php endif; ?> -- GitLab From 679825aecef1631e2ad2f161a4026743a5241b42 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 15:00:31 -0500 Subject: [PATCH 162/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- .../Review/view/adminhtml/templates/rating/options.phtml | 3 +-- .../view/adminhtml/templates/rating/stars/detailed.phtml | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml index b0712f11dec..8fe776fb345 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml @@ -5,14 +5,13 @@ */ // @codingStandardsIgnoreFile - ?> <div class="entry-edit-head"> <h4 class="icon-head head-edit-form fieldset-legend"><?php /* @escapeNotVerified */ echo __('Assigned Options') ?></h4> </div> <fieldset id="options_form"> <?php if (!$options): ?> - <?php for ($_i = 1;$_i <= 5;$_i++): ?> + <?php for ($_i = 1; $_i <= 5; $_i++): ?> <span class="field-row"> <label for="option_<?php /* @noEscape */ echo $_i ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> <input id="option_<?php /* @noEscape */ echo $_i ?>" name="option[<?php /* @noEscape */ echo $_i ?>][code]" value="<?php /* @noEscape */ echo $_i ?>" class="input-text" type="text" /> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml index bdc65c0fbbf..86ae33dae3e 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml @@ -5,7 +5,6 @@ */ // @codingStandardsIgnoreFile - ?> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> <div class="ratings-container"> -- GitLab From bf08600c13f1f342f220e4ab96efb1da2f409e5e Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 4 Aug 2016 15:12:43 -0500 Subject: [PATCH 163/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../Wishlist/view/frontend/templates/item/column/actions.phtml | 1 - .../Wishlist/view/frontend/templates/item/column/price.phtml | 1 - .../Wishlist/view/frontend/templates/item/column/remove.phtml | 1 - 3 files changed, 3 deletions(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml index 275d123f69d..e9316c8a12e 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/actions.phtml @@ -7,7 +7,6 @@ // @codingStandardsIgnoreFile /** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Actions $block */ -/* @var \Magento\Wishlist\Model\Item $item */ ?> <?php $children = $block->getChildNames(); ?> <?php if ($children): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml index beb082cc72a..94dfab4b348 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/price.phtml @@ -7,7 +7,6 @@ // @codingStandardsIgnoreFile /** @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Cart $block */ -/** @var \Magento\Wishlist\Model\Item $item */ ?> <?php foreach ($block->getChildNames() as $childName): ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index b358362c111..50b61d61457 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -7,7 +7,6 @@ // @codingStandardsIgnoreFile /* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ - ?> <a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @escapeNotVerified */ echo __('Remove Item') ?>" class="btn-remove action delete"> -- GitLab From d1f33d6b67983dfadb4382b321c63f3647ab3027 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 15:23:14 -0500 Subject: [PATCH 164/838] MAGETWO-56430: New newsletter template page is broken Removing escaping of getForm result --- .../Newsletter/view/adminhtml/templates/template/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index db61ffadc98..0b04d968314 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -17,7 +17,7 @@ use Magento\Framework\App\TemplateTypesInterface; <input type="hidden" id="change_flag_element" name="_change_type_flag" value="" /> <input type="hidden" id="save_as_flag" name="_save_as_flag" value="<?php echo $block->escapeHtmlAttr($block->getSaveAsFlag()) ?>" /> </div> - <?php echo $block->escapeHtml($block->getForm()) ?> + <?php /* noEscape */ echo $block->getForm() ?> </form> <form action="<?php echo $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="newsletter_template_preview_form" target="_blank"> <?php echo $block->getBlockHtml('formkey')?> -- GitLab From 9076d18a9d301faeae6dfcba8292fab696b95cfe Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 16:07:26 -0500 Subject: [PATCH 165/838] MAGETWO-55923: Eliminate @escapeNotVerified in Review Module Applying escape functions in templates --- .../Review/view/frontend/templates/customer/view.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml index 06c2f591661..9937fce922f 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml @@ -39,9 +39,9 @@ $product = $block->getProductData(); <?php $rating = ceil($_rating->getPercent()) ?> <div class="rating-summary item"> <span class="rating-label"><span><?php echo $block->escapeHtml($_rating->getRatingCode()) ?></span></span> - <div class="rating-result" title="<?php /* noEscape */ echo $rating; ?>%"> - <span style="width:<?php /* noEscape */ echo $rating; ?>%"> - <span><?php /* noEscape */ echo $rating; ?>%</span> + <div class="rating-result" title="<?php /* @noEscape */ echo $rating; ?>%"> + <span style="width:<?php /* @noEscape */ echo $rating; ?>%"> + <span><?php /* @noEscape */ echo $rating; ?>%</span> </span> </div> </div> -- GitLab From 94ac6de2a196f69743304436b1cde64898a5d500 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 4 Aug 2016 16:09:05 -0500 Subject: [PATCH 166/838] MAGETWO-56430: New newsletter template page is broken Removing escaping of getForm result --- .../Newsletter/view/adminhtml/templates/template/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index 0b04d968314..61bfd057d45 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -17,7 +17,7 @@ use Magento\Framework\App\TemplateTypesInterface; <input type="hidden" id="change_flag_element" name="_change_type_flag" value="" /> <input type="hidden" id="save_as_flag" name="_save_as_flag" value="<?php echo $block->escapeHtmlAttr($block->getSaveAsFlag()) ?>" /> </div> - <?php /* noEscape */ echo $block->getForm() ?> + <?php /* @noEscape */ echo $block->getForm() ?> </form> <form action="<?php echo $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="newsletter_template_preview_form" target="_blank"> <?php echo $block->getBlockHtml('formkey')?> -- GitLab From f01013acdf61482c6304352d3c1e2edc94d9c2c1 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 4 Aug 2016 16:14:03 -0500 Subject: [PATCH 167/838] MAGETWO-56098: New static test for the changed modules - Refactored test to only test those modules that have been refactored and new modules. - Added modules that are exempt from absence of @escapeNotVerified. --- .../Magento/Test/Php/XssPhtmlTemplateTest.php | 33 +++--- .../_files/whitelist/exempt_modules/ce.php | 100 ++++++++++++++++++ 2 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php diff --git a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php index bbe5286c8fb..4c7eebecaac 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/XssPhtmlTemplateTest.php @@ -15,23 +15,6 @@ use Magento\Framework\Component\ComponentRegistrar; */ class XssPhtmlTemplateTest extends \PHPUnit_Framework_TestCase { - /** - * @var array - */ - private $moduleList = [ - 'Magento_Customer', - 'Magento_Contact', - 'Magento_Cookie', - 'Magento_Customer', - 'Magento_Newsletter', - 'Magento_Persistent', - 'Magento_ProductAlert', - 'Magento_Review', - 'Magento_Rss', - 'Magento_Wishlist', - 'Magento_SendFriend' - ]; - /** * @return void */ @@ -75,9 +58,19 @@ class XssPhtmlTemplateTest extends \PHPUnit_Framework_TestCase public function testAbsenceOfEscapeNotVerifiedAnnotationInRefinedModules() { $componentRegistrar = new ComponentRegistrar(); + $exemptModules = []; + foreach (array_diff(scandir(__DIR__ . '/_files/whitelist/exempt_modules'), ['..', '.']) as $file) { + $exemptModules = array_merge( + $exemptModules, + include(__DIR__ . '/_files/whitelist/exempt_modules/' . $file) + ); + } + $result = ""; - foreach ($this->moduleList as $moduleName) { - $modulePath = $componentRegistrar->getPath(ComponentRegistrar::MODULE, $moduleName); + foreach ($componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) { + if (in_array($moduleName, $exemptModules)) { + continue; + } foreach (Files::init()->getFiles([$modulePath], '*.phtml') as $file) { $fileContents = file_get_contents($file); $pattern = "/\\/* @escapeNotVerified \\*\\/ echo (?!__).+/"; @@ -92,7 +85,7 @@ class XssPhtmlTemplateTest extends \PHPUnit_Framework_TestCase $this->assertEmpty( $result, "@escapeNotVerified annotation detected.\n" . - "Please use the correct escape strategy and remove annotation at : \n" . $result + "Please use the correct escape strategy and remove annotation at:\n" . $result ); } } diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php new file mode 100644 index 00000000000..82cd1881ce4 --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +/* These are the modules that have not been refactored from @escapeNotVerified yet. */ +return [ + 'Magento_Store', + 'Magento_AdvancedPricingImportExport', + 'Magento_Directory', + 'Magento_Theme', + 'Magento_Backend', + 'Magento_Backup', + 'Magento_Eav', + 'Magento_BundleImportExport', + 'Magento_CacheInvalidate', + 'Magento_AdminNotification', + 'Magento_Indexer', + 'Magento_CatalogImportExport', + 'Magento_Cms', + 'Magento_Rule', + 'Magento_Catalog', + 'Magento_Search', + 'Magento_CatalogUrlRewrite', + 'Magento_Widget', + 'Magento_Quote', + 'Magento_CheckoutAgreements', + 'Magento_SalesSequence', + 'Magento_CmsUrlRewrite', + 'Magento_Config', + 'Magento_ConfigurableImportExport', + 'Magento_Msrp', + 'Magento_Cron', + 'Magento_CurrencySymbol', + 'Magento_Bundle', + 'Magento_CustomerImportExport', + 'Magento_Deploy', + 'Magento_Developer', + 'Magento_Dhl', + 'Magento_Authorization', + 'Magento_Downloadable', + 'Magento_ImportExport', + 'Magento_Payment', + 'Magento_Email', + 'Magento_User', + 'Magento_Fedex', + 'Magento_Sales', + 'Magento_CatalogInventory', + 'Magento_GoogleAnalytics', + 'Magento_Ui', + 'Magento_GroupedImportExport', + 'Magento_GroupedProduct', + 'Magento_DownloadableImportExport', + 'Magento_Checkout', + 'Magento_Security', + 'Magento_LayeredNavigation', + 'Magento_Marketplace', + 'Magento_MediaStorage', + 'Magento_CatalogRule', + 'Magento_Multishipping', + 'Magento_ConfigurableProductNewsletter', + 'Magento_ConfigurableProduct', + 'Magento_OfflinePayments', + 'Magento_SalesRule', + 'Magento_PageCache', + 'Magento_Vault', + 'Magento_ProductVideo', + 'Magento_Authorizenet', + 'Magento_Reports', + 'Magento_RequireJs', + 'Magento_CatalogRuleConfigurable', + 'Magento_Paypal', + 'Magento_OfflineShipping', + 'Magento_GoogleAdwords', + 'Magento_SampleData', + 'Magento_CatalogSearch', + 'Magento_Integration', + 'Magento_Shipping', + 'Magento_Sitemap', + 'Magento_NewRelicReporting', + 'Magento_Swagger', + 'Magento_Swatches', + 'Magento_SwatchesLayeredNavigation', + 'Magento_Tax', + 'Magento_TaxImportExport', + 'Magento_GiftMessage', + 'Magento_Translation', + 'Magento_GoogleOptimizer', + 'Magento_Ups', + 'Magento_UrlRewrite', + 'Magento_EncryptionKey', + 'Magento_Usps', + 'Magento_Variable', + 'Magento_Braintree', + 'Magento_Version', + 'Magento_Webapi', + 'Magento_WebapiSecurity', + 'Magento_Weee', + 'Magento_CatalogWidget' +]; -- GitLab From d92285a05a5256938afd7e36846d83825109c4c5 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 4 Aug 2016 16:51:41 -0500 Subject: [PATCH 168/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module - Reverted change to deletion of templates. - Addressed comments from CR. --- .../Cms/view/frontend/templates/content.phtml | 10 ++++++++++ .../Cms/view/frontend/templates/meta.phtml | 15 +++++++++++++++ .../templates/widget/static_block/default.phtml | 5 ++++- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Cms/view/frontend/templates/content.phtml create mode 100644 app/code/Magento/Cms/view/frontend/templates/meta.phtml diff --git a/app/code/Magento/Cms/view/frontend/templates/content.phtml b/app/code/Magento/Cms/view/frontend/templates/content.phtml new file mode 100644 index 00000000000..3705cc6dce8 --- /dev/null +++ b/app/code/Magento/Cms/view/frontend/templates/content.phtml @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +?> +<?php /* @escapeNotVerified */ echo $pageData->getPageContent(); ?> diff --git a/app/code/Magento/Cms/view/frontend/templates/meta.phtml b/app/code/Magento/Cms/view/frontend/templates/meta.phtml new file mode 100644 index 00000000000..80c831774b1 --- /dev/null +++ b/app/code/Magento/Cms/view/frontend/templates/meta.phtml @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +?> +<?php if ($pageData->getPageMetaKeywords()): ?> + <meta name="keywords" content="<?php /* @escapeNotVerified */ echo $pageData->getPageMetaKeywords() ?>"/> +<?php endif; ?> +<?php if ($pageData->getPageMetaDescription()): ?> + <meta name="description" content="<?php /* @escapeNotVerified */ echo $pageData->getPageMetaDescription() ?>"/> +<?php endif; ?> diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml index 53c74826a32..4eb463ab3c3 100644 --- a/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml @@ -3,7 +3,10 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/* @var $block \Magento\Cms\Block\Widget\Block */ + ?> <div class="widget block block-static-block"> - <?php /* @noEscape */ echo $block->getText(); ?> + <?php echo $block->escapeHtml($block->getText()); ?> </div> -- GitLab From 54db8985d76acb9a90bb4fa8e3b59cfbe5d3bdc3 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 4 Aug 2016 17:02:48 -0500 Subject: [PATCH 169/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module - Fixed comments from CR. --- .../view/adminhtml/templates/instance/edit/layout.phtml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index 50e2b4faf96..90acc63a543 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var $block \Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Tab\Main\Layout */ + ?> <fieldset class="fieldset"> <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Layout Updates') ?></span></legend> @@ -38,7 +40,7 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<div class="fieldset-wrapper-content">'+ <?php foreach ($block->getDisplayOnContainers() as $container): ?> '<div class="no-display <?php echo $block->escapeJs($container['code']) ?> group_container" id="<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php echo $block->escapeHtml($container['name']) ?>]" />'+ + '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>]" />'+ '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][page_id]" value="<%- data.page_id %>" />'+ '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][layout_handle]" value="<?php echo $block->escapeJs($container['layout_handle']) ?>" />'+ '<table class="data-table">'+ @@ -79,7 +81,7 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php echo $block->escapeJs($container['code']) ?>\', \'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Open Chooser')) ?>">' + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_chooser_trigger.gif')) ?>" alt="<?php echo $block->escapeJs(__('Open Chooser')); ?>" />' + '</a> ' + - '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeHtmlAttr($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Apply')); ?>">' + + '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Apply')); ?>">' + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>" alt="<?php echo $block->escapeJs(__('Apply')); ?>" />' + '</a>' + '</p>'+ @@ -133,7 +135,7 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php echo $block->escapeHtml($block->getLayoutsChooser()) ?></td>'+ + '<td><?php echo $block->escapeJs($block->getLayoutsChooser()) ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ -- GitLab From a6caba3b1dd10924c862392d0efb0a5de13ecc26 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 4 Aug 2016 17:09:00 -0500 Subject: [PATCH 170/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../Magento/Wishlist/view/frontend/templates/options_list.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index acd198d0f83..2221b882b47 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -20,7 +20,7 @@ <dt class="label"><?php echo $block->escapeHtml($option['label']) ?></dt> <dd class="values"> <?php if (is_array($option['value'])): ?> - <?php echo nl2br($block->escapeHtml(implode("\n", $option['value']))) ?> + <?php /* @noEscape */ echo nl2br(implode("\n", $option['value'])) ?> <?php else: ?> <?php echo $block->escapeHtml($option['value']) ?> <?php endif; ?> -- GitLab From 59ce1a4a4995a10463d97b23f46d02fa3c3b054a Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 5 Aug 2016 10:23:42 +0300 Subject: [PATCH 171/838] MAGETWO-55271: Cover with Functional Tests --- .../AssertMultipleUpdateSuccessMessage.php | 24 ++++++++++++++++--- .../TestCase/ExtensionMultipleUpdateTest.php | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php index 1286f8939f7..f840cd49fb6 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php @@ -6,19 +6,37 @@ namespace Magento\Setup\Test\Constraint\Extension; use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Setup\Test\Fixture\Extension; +use Magento\Setup\Test\Page\Adminhtml\SetupWizard; /** * Class AssertMultipleUpdateSuccessMessage */ class AssertMultipleUpdateSuccessMessage extends AbstractConstraint { - public function processAssert() + /** + * Assert update of extensions is successful. + * + * @param SetupWizard $setupWizard + * @param Extension[] $extensions + * @param int $type + * @return void + */ + public function processAssert(SetupWizard $setupWizard, array $extensions, $type) { - + $assertSuccessMessage = $this->objectManager->get(AssertSuccessMessage::class); + foreach ($extensions as $extension) { + $assertSuccessMessage->processAssert($setupWizard, $extension, $type); + } } + /** + * Returns a string representation of successful assertion. + * + * @return string + */ public function toString() { - // TODO: Implement toString() method. + return "Extension Updater success message is correct."; } } diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index 44be6f7e958..cdcc797f12f 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -90,7 +90,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest $assertMultipleUpdateSuccessMessage->processAssert( $this->setupWizard, $extensions, - AssertSuccessMessage::TYPE_INSTALL + AssertSuccessMessage::TYPE_UPDATE ); // Uninstall installed extensions -- GitLab From 7f665e2762c20f13b61ee214a4fdf67ff04eef9f Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 5 Aug 2016 12:56:49 +0300 Subject: [PATCH 172/838] MAGETWO-55268: Upgrade/Check Requirements process --- setup/pub/magento/setup/readiness-check.js | 48 ++++++++++++++++++- .../magento/setup/update-extension-grid.js | 6 +++ .../view/magento/setup/readiness-check.phtml | 2 +- .../setup/readiness-check/progress.phtml | 33 +++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/setup/pub/magento/setup/readiness-check.js b/setup/pub/magento/setup/readiness-check.js index cdeb9f1b0c9..9ed20b55e14 100644 --- a/setup/pub/magento/setup/readiness-check.js +++ b/setup/pub/magento/setup/readiness-check.js @@ -11,6 +11,7 @@ angular.module('readiness-check', []) $scope.titles = $localStorage.titles; $scope.moduleName = $localStorage.moduleName; $scope.progressCounter = COUNTER; + $rootScope.needReCheck = false; $scope.startProgress = function() { ++$scope.progressCounter; }; @@ -359,5 +360,50 @@ angular.module('readiness-check', []) $actionString +='ed'; } return $actionString; - } + }; + + $scope.getExtensionsList = function () { + return $scope.componentDependency.packages ? $scope.componentDependency.packages : {}; + }; + + $scope.removeExtension = function (name) { + delete $scope.componentDependency.packages[name]; + $localStorage.packages = $scope.componentDependency.packages; + $rootScope.needReCheck = true; + }; + + $scope.getCurrentVersion = function (name) { + if ($scope.getExtensionInfo(name).hasOwnProperty('currentVersion')) { + return $scope.getExtensionInfo(name)['currentVersion']; + } + + return ''; + }; + + $scope.getVersionsList = function (name) { + if ($scope.getExtensionInfo(name).hasOwnProperty('versions')) { + return $scope.getExtensionInfo(name)['versions']; + } + + return {}; + }; + + $scope.getExtensionInfo = function (name) { + var extensionsVersions = $localStorage.extensionsVersions; + return extensionsVersions.hasOwnProperty(name) ? extensionsVersions[name] : {}; + }; + + $scope.versionChanged = function () { + $rootScope.needReCheck = true; + }; + + $scope.getObjectSize = function (obj) { + var size = 0, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + ++size; + } + } + return size; + }; }]); diff --git a/setup/pub/magento/setup/update-extension-grid.js b/setup/pub/magento/setup/update-extension-grid.js index 80dd0e9cb7c..ab14a76610a 100644 --- a/setup/pub/magento/setup/update-extension-grid.js +++ b/setup/pub/magento/setup/update-extension-grid.js @@ -12,11 +12,16 @@ angular.module('update-extension-grid', ['ngStorage', 'clickOut']) $http.get('index.php/updateExtensionGrid/extensions').success(function(data) { $scope.error = false; $scope.errorMessage = ''; + $scope.extensionsVersions = {}; $scope.multipleChoiceService = multipleChoiceService; $scope.multipleChoiceService.reset(); angular.forEach(data.extensions, function(extension) { extension.updateVersion = extension.latestVersion; $scope.multipleChoiceService.addExtension(extension.name, extension.latestVersion); + $scope.extensionsVersions[extension.name] = { + 'currentVersion': extension.version, + 'versions': extension.versions + }; }); $scope.extensions = data.extensions; $scope.total = data.total; @@ -24,6 +29,7 @@ angular.module('update-extension-grid', ['ngStorage', 'clickOut']) $scope.rowLimit = 20; $scope.numberOfPages = Math.ceil($scope.total / $scope.rowLimit); $scope.isHiddenSpinner = true; + $localStorage.extensionsVersions = $scope.extensionsVersions; }); paginationService.initWatchers($scope); diff --git a/setup/view/magento/setup/readiness-check.phtml b/setup/view/magento/setup/readiness-check.phtml index 7a228ff7e9a..2aaf4de649b 100644 --- a/setup/view/magento/setup/readiness-check.phtml +++ b/setup/view/magento/setup/readiness-check.phtml @@ -11,7 +11,7 @@ type="button" class="btn btn-prime" ng-click="nextState()" - ng-disabled="checkingInProgress() || hasErrors" + ng-disabled="needReCheck || checkingInProgress() || hasErrors" >Next</button> </div> <div class="btn-wrap btn-wrap-triangle-left btn-wrap-prev"> diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 3b7c7a38cc8..4c52352bf07 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -7,6 +7,39 @@ // @codingStandardsIgnoreFile ?> +<div class="message" ng-show="getObjectSize(getExtensionsList()) > 1"> + <div><strong>Extensions to {{$state.current.type}}:</strong></div> + <div>You can change the version or remove the extension from the updating.</div> + <div class="row" ng-repeat="extension in getExtensionsList()"> + <div class="col-m-3">{{extension.name}}</div> + <div class="col-m-1">{{getCurrentVersion(extension.name)}}</i></div> + <div class="col-m-2"> + <span ng-show="checkingInProgress()">{{extension.version}}</span> + <select ng-change="versionChanged()" + ng-model="extension.version" + ng-hide="checkingInProgress()" + > + <option ng-repeat="version in getVersionsList(extension.name)" + value="{{version}}" + >Version {{version}}</option> + </select> + </div> + <div class="col-m-1"> + <a href="#" + ng-click="removeExtension(extension.name)" + ng-show="!checkingInProgress()" + > + remove + </a> + </div> + </div> +</div> + +<div class="message message-warning" ng-show="needReCheck && !checkingInProgress()"> + After your changes You need to recheck component dependency. Please click + <a href="#" ng-click="$state.forceReload()">here</a>. +</div> + <div ng-switch="isCompleted()"> <div ng-switch-when="true" ng-switch="hasErrors"> -- GitLab From 95bc24c215a77c5ae87df1b1a175be6a47a5e43e Mon Sep 17 00:00:00 2001 From: Roman Liukshyn <rliukshyn@magento.com> Date: Thu, 4 Aug 2016 18:10:47 +0300 Subject: [PATCH 173/838] MAGETWO-56467: Free shipping threshold fields are mixed up in UPS and Fedex configurations --- app/code/Magento/Fedex/etc/adminhtml/system.xml | 4 ++-- app/code/Magento/Ups/etc/adminhtml/system.xml | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Fedex/etc/adminhtml/system.xml b/app/code/Magento/Fedex/etc/adminhtml/system.xml index 1de61c2c154..16966322f25 100644 --- a/app/code/Magento/Fedex/etc/adminhtml/system.xml +++ b/app/code/Magento/Fedex/etc/adminhtml/system.xml @@ -101,11 +101,11 @@ <source_model>Magento\Fedex\Model\Source\Freemethod</source_model> </field> <field id="free_shipping_enable" translate="label" type="select" sortOrder="220" showInDefault="1" showInWebsite="1" showInStore="0"> - <label>Free Shipping Amount Threshold</label> + <label>Enable Free Shipping Threshold</label> <source_model>Magento\Config\Model\Config\Source\Enabledisable</source_model> </field> <field id="free_shipping_subtotal" translate="label" type="text" sortOrder="230" showInDefault="1" showInWebsite="1" showInStore="0"> - <label>Enable Free Shipping Threshold</label> + <label>Free Shipping Amount Threshold</label> <validate>validate-number validate-zero-or-greater</validate> <depends> <field id="free_shipping_enable">1</field> diff --git a/app/code/Magento/Ups/etc/adminhtml/system.xml b/app/code/Magento/Ups/etc/adminhtml/system.xml index dd83ab7c4ed..39bd613974d 100644 --- a/app/code/Magento/Ups/etc/adminhtml/system.xml +++ b/app/code/Magento/Ups/etc/adminhtml/system.xml @@ -32,12 +32,15 @@ <source_model>Magento\Ups\Model\Config\Source\Container</source_model> </field> <field id="free_shipping_enable" translate="label" type="select" sortOrder="210" showInDefault="1" showInWebsite="1" showInStore="0"> - <label>Free Shipping Amount Threshold</label> + <label>Enable Free Shipping Threshold</label> <source_model>Magento\Config\Model\Config\Source\Enabledisable</source_model> </field> <field id="free_shipping_subtotal" translate="label" type="text" sortOrder="220" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Free Shipping Amount Threshold</label> <validate>validate-number validate-zero-or-greater</validate> + <depends> + <field id="free_shipping_enable">1</field> + </depends> </field> <field id="dest_type" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>Destination Type</label> -- GitLab From ce1160fbf7d1d08bc2d0d6f3d4c648074271024b Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Fri, 5 Aug 2016 14:20:57 +0300 Subject: [PATCH 174/838] MAGETWO-56344: [Github] #5902 Braintree doesn't work when using table prefixing --- .../Model/ResourceModel/PaymentToken.php | 2 +- .../Model/ResourceModel/PaymentTokenTest.php | 114 ++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Vault/Model/ResourceModel/PaymentTokenTest.php diff --git a/app/code/Magento/Vault/Model/ResourceModel/PaymentToken.php b/app/code/Magento/Vault/Model/ResourceModel/PaymentToken.php index e7644080abb..b9ffc69cf7f 100644 --- a/app/code/Magento/Vault/Model/ResourceModel/PaymentToken.php +++ b/app/code/Magento/Vault/Model/ResourceModel/PaymentToken.php @@ -104,7 +104,7 @@ class PaymentToken extends AbstractDb $connection = $this->getConnection(); $select = $connection->select() - ->from(InstallSchema::ORDER_PAYMENT_TO_PAYMENT_TOKEN_TABLE) + ->from($this->getTable(InstallSchema::ORDER_PAYMENT_TO_PAYMENT_TOKEN_TABLE)) ->where('order_payment_id = ?', (int) $orderPaymentId) ->where('payment_token_id =?', (int) $paymentTokenId); diff --git a/dev/tests/integration/testsuite/Magento/Vault/Model/ResourceModel/PaymentTokenTest.php b/dev/tests/integration/testsuite/Magento/Vault/Model/ResourceModel/PaymentTokenTest.php new file mode 100644 index 00000000000..88974f0d9cc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Vault/Model/ResourceModel/PaymentTokenTest.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Vault\Model\ResourceModel; + +use Magento\Braintree\Model\Ui\PayPal\ConfigProvider as PayPalConfigProvider; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Sales\Model\Order; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Vault\Model\PaymentTokenManagement; +use Magento\Vault\Setup\InstallSchema; + +class PaymentTokenTest extends \PHPUnit_Framework_TestCase +{ + const CUSTOMER_ID = 1; + const TOKEN = 'mx29vk'; + const ORDER_INCREMENT_ID = '100000001'; + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var PaymentToken + */ + private $paymentToken; + + /** + * @var ResourceConnection + */ + private $resource; + + /** + * @var AdapterInterface + */ + private $connection; + + /** + * @var PaymentTokenManagement + */ + private $paymentTokenManagement; + + /** + * @var Order + */ + private $order; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->order = $this->objectManager->create(Order::class); + $this->paymentToken = $this->objectManager->create(PaymentToken::class); + $this->paymentTokenManagement = $this->objectManager->get(PaymentTokenManagement::class); + + $this->resource = $this->objectManager->get(ResourceConnection::class); + $this->connection = $this->resource->getConnection(); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order.php + * @magentoDataFixture Magento/Braintree/_files/paypal_vault_token.php + */ + public function testAddLinkToOrderPaymentExists() + { + $this->order->loadByIncrementId(self::ORDER_INCREMENT_ID); + $paymentToken = $this->paymentTokenManagement + ->getByGatewayToken(self::TOKEN, PayPalConfigProvider::PAYPAL_CODE, self::CUSTOMER_ID); + + $this->connection->insert( + $this->resource->getTableName(InstallSchema::ORDER_PAYMENT_TO_PAYMENT_TOKEN_TABLE), + [ + 'order_payment_id' => $this->order->getPayment()->getEntityId(), + 'payment_token_id' => $paymentToken->getEntityId() + ] + ); + + static::assertTrue( + $this->paymentToken->addLinkToOrderPayment( + $paymentToken->getEntityId(), + $this->order->getPayment()->getEntityId() + ) + ); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order.php + * @magentoDataFixture Magento/Braintree/_files/paypal_vault_token.php + */ + public function testAddLinkToOrderPaymentCreate() + { + $this->order->loadByIncrementId(self::ORDER_INCREMENT_ID); + $paymentToken = $this->paymentTokenManagement + ->getByGatewayToken(self::TOKEN, PayPalConfigProvider::PAYPAL_CODE, self::CUSTOMER_ID); + + $select = $this->connection->select() + ->from($this->resource->getTableName(InstallSchema::ORDER_PAYMENT_TO_PAYMENT_TOKEN_TABLE)) + ->where('order_payment_id = ?', (int) $this->order->getPayment()->getEntityId()) + ->where('payment_token_id =?', (int) $paymentToken->getEntityId()); + + static::assertEmpty($this->connection->fetchRow($select)); + static::assertTrue( + $this->paymentToken->addLinkToOrderPayment( + $paymentToken->getEntityId(), + $this->order->getPayment()->getEntityId() + ) + ); + static::assertNotEmpty($this->connection->fetchRow($select)); + } +} -- GitLab From e8f237cd62301238cb154f0fe0b83d19787d3135 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Fri, 5 Aug 2016 15:38:26 +0300 Subject: [PATCH 175/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - refactor method isInvalid --- .../Magento/Ui/view/base/web/js/form/element/abstract.js | 6 +++--- app/code/Magento/Ui/view/base/web/js/form/form.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js index 6191a78d29a..60cc836c719 100755 --- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js @@ -77,10 +77,10 @@ define([ /** * Checks if component has error. * - * @returns {Boolean} + * @returns {Object} */ - isInvalid: function () { - return this.error() && this.error().length ? this : false; + checkInvalid: function () { + return this.error() && this.error().length ? this : null; }, /** diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js index 2431d19cf9d..0a3d6ee5850 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -264,7 +264,7 @@ define([ * @returns {Object} */ focusInvalid: function () { - var invalidField = _.find(this.delegate('isInvalid')); + var invalidField = _.find(this.delegate('checkInvalid')); if (!_.isUndefined(invalidField) && _.isFunction(invalidField.focused)) { invalidField.focused(true); -- GitLab From c75106d9ab8bcef3c667316c055d17d3c7dee8c9 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 5 Aug 2016 15:39:38 +0300 Subject: [PATCH 176/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../magento/setup/readiness-check/progress.phtml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 4c52352bf07..2aa7b6cc829 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -7,9 +7,11 @@ // @codingStandardsIgnoreFile ?> -<div class="message" ng-show="getObjectSize(getExtensionsList()) > 1"> +<div class="message" ng-class="{'message-warning':needReCheck && !checkingInProgress()}" + ng-show="getObjectSize(getExtensionsList()) > 1" +> <div><strong>Extensions to {{$state.current.type}}:</strong></div> - <div>You can change the version or remove the extension from the updating.</div> + <div class="row">You can change the version or remove the extension from the updating.</div> <div class="row" ng-repeat="extension in getExtensionsList()"> <div class="col-m-3">{{extension.name}}</div> <div class="col-m-1">{{getCurrentVersion(extension.name)}}</i></div> @@ -33,11 +35,10 @@ </a> </div> </div> -</div> - -<div class="message message-warning" ng-show="needReCheck && !checkingInProgress()"> - After your changes You need to recheck component dependency. Please click - <a href="#" ng-click="$state.forceReload()">here</a>. + <div ng-show="needReCheck && !checkingInProgress()"> + <strong>After your changes You need to recheck component dependency. Please click + <a href="#" ng-click="$state.forceReload()">here</a>.</strong> + </div> </div> <div ng-switch="isCompleted()"> -- GitLab From b5e2cf628b8597cdbf63c16ffb9b8d46761ddd77 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 5 Aug 2016 17:37:50 +0300 Subject: [PATCH 177/838] MAGETWO-55271: Cover with Functional Tests --- .../Setup/Test/TestCase/ExtensionMultipleUpdateTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index cdcc797f12f..c99fd15a02d 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -31,6 +31,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest * @param AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck * @param AssertSuccessMessage $assertSuccessMessage * @param AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage + * @param AssertSelectSeveralExtensions $assertSelectSeveralExtensions * @param $needAuthentication * @param array $extensions */ @@ -43,6 +44,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck, AssertSuccessMessage $assertSuccessMessage, AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage, + AssertSelectSeveralExtensions $assertSelectSeveralExtensions, $needAuthentication, array $extensions ) { @@ -76,7 +78,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest $this->setupWizard->getExtensionsGrid()->clickUpdateButton(); // Select several extensions on grid and check it - $this->setupWizard->getExtensionsUpdateGrid()->selectSeveralExtensions($extensions); + $assertSelectSeveralExtensions->processAssert($this->setupWizard->getExtensionsUpdateGrid(), $extensions); // Click general "Update" button $this->setupWizard->getExtensionsUpdateGrid()->clickUpdateAllButton(); -- GitLab From b855b4cc8282cf7a0480d8d27a2e47e0f441552d Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 5 Aug 2016 17:46:05 +0300 Subject: [PATCH 178/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../setup/readiness-check/progress.phtml | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 2aa7b6cc829..b47bc7b5cb3 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -8,33 +8,29 @@ ?> <div class="message" ng-class="{'message-warning':needReCheck && !checkingInProgress()}" - ng-show="getObjectSize(getExtensionsList()) > 1" + ng-show="getObjectSize(getExtensionsList()) > 0" > <div><strong>Extensions to {{$state.current.type}}:</strong></div> - <div class="row">You can change the version or remove the extension from the updating.</div> - <div class="row" ng-repeat="extension in getExtensionsList()"> - <div class="col-m-3">{{extension.name}}</div> - <div class="col-m-1">{{getCurrentVersion(extension.name)}}</i></div> - <div class="col-m-2"> - <span ng-show="checkingInProgress()">{{extension.version}}</span> + <div>You can change the version or remove the extension from the updating.</div> + + <ul class="list"> + <li ng-repeat="extension in getExtensionsList()"> + {{extension.name}} {{getCurrentVersion(extension.name)}} to <select ng-change="versionChanged()" ng-model="extension.version" - ng-hide="checkingInProgress()" + ng-disabled="checkingInProgress()" > <option ng-repeat="version in getVersionsList(extension.name)" + ng-selected="version == extension.version" value="{{version}}" >Version {{version}}</option> </select> - </div> - <div class="col-m-1"> - <a href="#" + <button style="padding-top: 0;" class="abs-action-delete" ng-click="removeExtension(extension.name)" - ng-show="!checkingInProgress()" - > - remove - </a> - </div> - </div> + ng-show="!checkingInProgress() && getObjectSize(getExtensionsList()) > 1"></button> + </li> + </ul> + <div ng-show="needReCheck && !checkingInProgress()"> <strong>After your changes You need to recheck component dependency. Please click <a href="#" ng-click="$state.forceReload()">here</a>.</strong> -- GitLab From e6a8d10196e762e5c1f0471b061849fa32a28e3e Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Fri, 5 Aug 2016 18:16:09 +0300 Subject: [PATCH 179/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - Fix JavaScript code style --- .../Magento/Ui/view/base/web/js/grid/editing/editor.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js index 47beec3de2f..d645e6aff16 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js @@ -487,8 +487,6 @@ define([ /** * Counts number of invalid fields across all active records. - * - * @returns {Number} */ countErrors: function () { var errorsCount = 0; @@ -504,11 +502,10 @@ define([ /** * Translatable error message text. - * - * @param {String} */ countErrorsMessage: function () { - return $t('There are {placeholder} messages requires your attention.'). replace('{placeholder}', this.countErrors()); + return $t('There are {placeholder} messages requires your attention.') + .replace('{placeholder}', this.countErrors()); }, /** -- GitLab From c7381ed1ba5308f506ae049f896d85c323d00880 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Fri, 5 Aug 2016 18:29:03 +0300 Subject: [PATCH 180/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - Fix JavaScript code style --- app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js index d645e6aff16..0fc16010af3 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/editor.js @@ -487,6 +487,8 @@ define([ /** * Counts number of invalid fields across all active records. + * + * @returns {Number} */ countErrors: function () { var errorsCount = 0; @@ -502,6 +504,8 @@ define([ /** * Translatable error message text. + * + * @returns {String} */ countErrorsMessage: function () { return $t('There are {placeholder} messages requires your attention.') -- GitLab From bcd3e02537db07bef4a06c4c586dc7d8e652b2ca Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Fri, 5 Aug 2016 18:39:27 +0300 Subject: [PATCH 181/838] MAGETWO-55364: [WCAG 2.0 AA] Add Aria-Labels for Color Swatches - Fix JavaScript code style --- .../Swatches/view/frontend/web/js/swatch-renderer.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index c4d16c95328..4e79c42dd6a 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -336,7 +336,9 @@ define([ if ($widget.options.enableControlLabel) { label += - '<span id="' + controlLabelId + '" class="' + classes.attributeLabelClass + '">' + item.label + '</span>' + + '<span id="' + controlLabelId + '" class="' + classes.attributeLabelClass + '">' + + item.label + + '</span>' + '<span class="' + classes.attributeSelectedOptionLabelClass + '"></span>'; } @@ -547,7 +549,8 @@ define([ */ _EventListener: function () { var $widget = this, - options = this.options.classes; + options = this.options.classes, + target; $widget.element.on('click', '.' + options.optionClass, function () { return $widget._OnClick($(this), $widget); @@ -564,8 +567,8 @@ define([ }); $widget.element.on('keydown', function (e) { - if (e.which == 13) { - var target = $(e.target); + if (e.which === 13) { + target = $(e.target); if (target.is('.' + options.optionClass)) { return $widget._OnClick(target, $widget); -- GitLab From cf31fc808129084a00cd9031d27d38c696771f7b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 5 Aug 2016 11:08:23 -0500 Subject: [PATCH 182/838] MAGETWO-56098: New static test for the changed modules --- .../_files/whitelist/exempt_modules/ce.php | 92 +++++-------------- 1 file changed, 24 insertions(+), 68 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php index 82cd1881ce4..f6eac1a5517 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -5,96 +5,52 @@ */ /* These are the modules that have not been refactored from @escapeNotVerified yet. */ return [ - 'Magento_Store', - 'Magento_AdvancedPricingImportExport', - 'Magento_Directory', - 'Magento_Theme', + 'Magento_AdminNotification', 'Magento_Backend', 'Magento_Backup', - 'Magento_Eav', - 'Magento_BundleImportExport', - 'Magento_CacheInvalidate', - 'Magento_AdminNotification', - 'Magento_Indexer', - 'Magento_CatalogImportExport', - 'Magento_Cms', - 'Magento_Rule', + 'Magento_Bundle', 'Magento_Catalog', - 'Magento_Search', - 'Magento_CatalogUrlRewrite', - 'Magento_Widget', - 'Magento_Quote', - 'Magento_CheckoutAgreements', - 'Magento_SalesSequence', - 'Magento_CmsUrlRewrite', + 'Magento_CatalogInventory', + 'Magento_CatalogRule', + 'Magento_CatalogSearch', + 'Magento_CatalogWidget', + 'Magento_Checkout', + 'Magento_Cms', 'Magento_Config', - 'Magento_ConfigurableImportExport', - 'Magento_Msrp', - 'Magento_Cron', + 'Magento_ConfigurableProduct', 'Magento_CurrencySymbol', - 'Magento_Bundle', - 'Magento_CustomerImportExport', - 'Magento_Deploy', - 'Magento_Developer', - 'Magento_Dhl', - 'Magento_Authorization', + 'Magento_Directory', 'Magento_Downloadable', - 'Magento_ImportExport', - 'Magento_Payment', 'Magento_Email', - 'Magento_User', - 'Magento_Fedex', - 'Magento_Sales', - 'Magento_CatalogInventory', + 'Magento_GiftMessage', + 'Magento_GoogleAdwords', 'Magento_GoogleAnalytics', - 'Magento_Ui', - 'Magento_GroupedImportExport', 'Magento_GroupedProduct', - 'Magento_DownloadableImportExport', - 'Magento_Checkout', - 'Magento_Security', + 'Magento_ImportExport', + 'Magento_Integration', 'Magento_LayeredNavigation', 'Magento_Marketplace', 'Magento_MediaStorage', - 'Magento_CatalogRule', + 'Magento_Msrp', 'Magento_Multishipping', - 'Magento_ConfigurableProductNewsletter', - 'Magento_ConfigurableProduct', - 'Magento_OfflinePayments', - 'Magento_SalesRule', 'Magento_PageCache', - 'Magento_Vault', + 'Magento_Paypal', 'Magento_ProductVideo', - 'Magento_Authorizenet', 'Magento_Reports', - 'Magento_RequireJs', - 'Magento_CatalogRuleConfigurable', - 'Magento_Paypal', - 'Magento_OfflineShipping', - 'Magento_GoogleAdwords', - 'Magento_SampleData', - 'Magento_CatalogSearch', - 'Magento_Integration', + 'Magento_Sales', + 'Magento_Search', + 'Magento_Security', 'Magento_Shipping', - 'Magento_Sitemap', - 'Magento_NewRelicReporting', + 'Magento_Store', 'Magento_Swagger', 'Magento_Swatches', - 'Magento_SwatchesLayeredNavigation', 'Magento_Tax', 'Magento_TaxImportExport', - 'Magento_GiftMessage', + 'Magento_Theme', 'Magento_Translation', - 'Magento_GoogleOptimizer', - 'Magento_Ups', + 'Magento_Ui', 'Magento_UrlRewrite', - 'Magento_EncryptionKey', - 'Magento_Usps', - 'Magento_Variable', - 'Magento_Braintree', - 'Magento_Version', - 'Magento_Webapi', - 'Magento_WebapiSecurity', + 'Magento_User', 'Magento_Weee', - 'Magento_CatalogWidget' + 'Magento_Widget', ]; -- GitLab From ee925ed49fbaba873652a4ba661bf54a2187fcdb Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 5 Aug 2016 11:29:23 -0500 Subject: [PATCH 183/838] MAGETWO-56098: New static test for the changed modules --- .../Magento/Test/Php/_files/whitelist/exempt_modules/ce.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php index f6eac1a5517..077bc4138d1 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -15,6 +15,7 @@ return [ 'Magento_CatalogSearch', 'Magento_CatalogWidget', 'Magento_Checkout', + 'Magento_CheckoutAgreements', 'Magento_Cms', 'Magento_Config', 'Magento_ConfigurableProduct', -- GitLab From cda2bd4ce9b743a115e474041c06592b1ec995f7 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Fri, 5 Aug 2016 11:55:40 -0500 Subject: [PATCH 184/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module - Added noEscape annotation. --- app/code/Magento/Cms/view/frontend/templates/content.phtml | 2 +- app/code/Magento/Cms/view/frontend/templates/meta.phtml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Cms/view/frontend/templates/content.phtml b/app/code/Magento/Cms/view/frontend/templates/content.phtml index 3705cc6dce8..29d92eb4f82 100644 --- a/app/code/Magento/Cms/view/frontend/templates/content.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/content.phtml @@ -7,4 +7,4 @@ // @codingStandardsIgnoreFile ?> -<?php /* @escapeNotVerified */ echo $pageData->getPageContent(); ?> +<?php /* @noEscape */ echo $pageData->getPageContent(); ?> diff --git a/app/code/Magento/Cms/view/frontend/templates/meta.phtml b/app/code/Magento/Cms/view/frontend/templates/meta.phtml index 80c831774b1..d6e3b81b8cb 100644 --- a/app/code/Magento/Cms/view/frontend/templates/meta.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/meta.phtml @@ -8,8 +8,8 @@ ?> <?php if ($pageData->getPageMetaKeywords()): ?> - <meta name="keywords" content="<?php /* @escapeNotVerified */ echo $pageData->getPageMetaKeywords() ?>"/> + <meta name="keywords" content="<?php /* @noEscape */ echo $pageData->getPageMetaKeywords() ?>"/> <?php endif; ?> <?php if ($pageData->getPageMetaDescription()): ?> - <meta name="description" content="<?php /* @escapeNotVerified */ echo $pageData->getPageMetaDescription() ?>"/> + <meta name="description" content="<?php /* @noEscape */ echo $pageData->getPageMetaDescription() ?>"/> <?php endif; ?> -- GitLab From 67021d290c65e47152bde43b11461dbd48b89d4c Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 5 Aug 2016 13:25:18 -0500 Subject: [PATCH 185/838] MAGETWO-55927: Eliminate @escapeNotVerified in UrlRewrite Module Applying escape functions in templates --- .../UrlRewrite/view/adminhtml/templates/categories.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml index 6b464048873..6a2508b048c 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml @@ -13,14 +13,14 @@ <div class="content content-category-tree"> <input type="hidden" name="categories" id="product_categories" value="" /> <?php if ($block->getRoot()): ?> - <div data-mage-init="<?php /* noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( + <div data-mage-init='<?php /* noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( [ 'categoryTree' => [ 'data' => $block->getTreeArray(), 'url' => $block->escapeUrl($block->getLoadTreeUrl()), ], ] - ); ?>" class="jstree-default"></div> + ); ?>' class="jstree-default"></div> <?php endif; ?> </div> </fieldset> -- GitLab From 5412156a984c59bc50d5f38fd0065fae95bc5b42 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 5 Aug 2016 13:42:17 -0500 Subject: [PATCH 186/838] MAGETWO-56098: New static test for the changed modules Applying escape functions in templates --- .../Cookie/view/frontend/templates/html/notices.phtml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index d223f7ec71f..61afce2979d 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -6,9 +6,9 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Cookie\Block\Html\Notices $block */ ?> -<?php /** @var \Magento\Cookie\Block\Html\Notices $block */ ?> -<?php if ($this->helper('Magento\Cookie\Helper\Cookie')->isUserNotAllowSaveCookie()): ?> +<?php if ($this->helper(\Magento\Cookie\Helper\Cookie::class)->isUserNotAllowSaveCookie()): ?> <div class="message global cookie" id="notice-cookie-block" style="display: none"> <div class="content"> <p> @@ -27,9 +27,9 @@ "#notice-cookie-block": { "cookieNotices": { "cookieAllowButtonSelector": "#btn-cookie-allow", - "cookieName": "<?php echo $block->escapeJs(\Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE) ?>", - "cookieValue": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, - "cookieLifetime": <?php /* @noEscape */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>, + "cookieName": "<?php echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", + "cookieValue": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getAcceptedSaveCookiesWebsiteIds() ?>, + "cookieLifetime": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getCookieRestrictionLifetime()?>, "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" } } -- GitLab From 60cdb49af8010e62726c0a8dede01dbd6ae027b5 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Fri, 5 Aug 2016 16:08:15 -0500 Subject: [PATCH 187/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module - fix static. --- .../view/adminhtml/templates/instance/edit/layout.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index 90acc63a543..612053a6ab0 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** @var $block \Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Tab\Main\Layout */ +/** @var \Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Tab\Main\Layout $block */ ?> <fieldset class="fieldset"> @@ -247,7 +247,7 @@ var WidgetInstance = { } forElm = pageGroup.down('input.for_'+data.for_value); if (forElm) { - /* + /** * IE browsers fix: remove default checked attribute in radio form element * to check others radio form elements in future */ -- GitLab From 85ecf121c10912de2e54ccd9acc3b6288fecadf6 Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Mon, 8 Aug 2016 10:15:12 +0300 Subject: [PATCH 188/838] MAGETWO-55953: Exception occurs when tracking shipment with invalid FedEx tracking number - Updated wsdl schema - Refactored response parsing for new schema changes - Refactored unit tests - Refactored tracking details view --- app/code/Magento/Fedex/Model/Carrier.php | 318 +++-- .../Fedex/Test/Unit/Model/CarrierTest.php | 602 +++++++-- ...kService_v5.wsdl => TrackService_v10.wsdl} | 1181 ++++++++++++++--- .../frontend/templates/tracking/details.phtml | 95 ++ .../frontend/templates/tracking/popup.phtml | 180 +-- .../templates/tracking/progress.phtml | 43 + 6 files changed, 1839 insertions(+), 580 deletions(-) rename app/code/Magento/Fedex/etc/wsdl/{TrackService_v5.wsdl => TrackService_v10.wsdl} (63%) create mode 100644 app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml create mode 100644 app/code/Magento/Shipping/view/frontend/templates/tracking/progress.phtml diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php index 4f8aae4962d..b3ffabf74da 100644 --- a/app/code/Magento/Fedex/Model/Carrier.php +++ b/app/code/Magento/Fedex/Model/Carrier.php @@ -126,6 +126,18 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'Key', 'Password', 'MeterNumber', ]; + /** + * Version of tracking service + * @var int + */ + private static $trackServiceVersion = 10; + + /** + * List of TrackReply errors + * @var array + */ + private static $trackingErrors = ['FAILURE', 'ERROR']; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory @@ -193,7 +205,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C $wsdlBasePath = $configReader->getModuleDir(Dir::MODULE_ETC_DIR, 'Magento_Fedex') . '/wsdl/'; $this->_shipServiceWsdl = $wsdlBasePath . 'ShipService_v10.wsdl'; $this->_rateServiceWsdl = $wsdlBasePath . 'RateService_v10.wsdl'; - $this->_trackServiceWsdl = $wsdlBasePath . 'TrackService_v5.wsdl'; + $this->_trackServiceWsdl = $wsdlBasePath . 'TrackService_v' . self::$trackServiceVersion . '.wsdl'; } /** @@ -371,6 +383,9 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C */ public function getResult() { + if (!$this->_result) { + $this->_result = $this->_trackFactory->create(); + } return $this->_result; } @@ -646,7 +661,6 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C { $r = $this->_rawRequest; $xml = $this->_xmlElFactory->create( - ['data' => '<?xml version = "1.0" encoding = "UTF-8"?><FDXRateAvailableServicesRequest/>'] ); @@ -1035,9 +1049,16 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'AccountNumber' => $this->getConfigData('account'), 'MeterNumber' => $this->getConfigData('meter_number'), ], - 'Version' => ['ServiceId' => 'trck', 'Major' => '5', 'Intermediate' => '0', 'Minor' => '0'], - 'PackageIdentifier' => ['Type' => 'TRACKING_NUMBER_OR_DOORTAG', 'Value' => $tracking], - 'IncludeDetailedScans' => 1, + 'Version' => [ + 'ServiceId' => 'trck', + 'Major' => self::$trackServiceVersion, + 'Intermediate' => '0', + 'Minor' => '0', + ], + 'SelectionDetails' => [ + 'PackageIdentifier' => ['Type' => 'TRACKING_NUMBER_OR_DOORTAG', 'Value' => $tracking], + ], + 'ProcessingOptions' => 'INCLUDE_DETAILED_SCANS' ]; $requestString = serialize($trackRequest); $response = $this->_getCachedQuotes($requestString); @@ -1064,114 +1085,45 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C /** * Parse tracking response * - * @param string[] $trackingValue + * @param string $trackingValue * @param \stdClass $response * @return void - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - protected function _parseTrackingResponse($trackingValue, $response) + protected function _parseTrackingResponse($trackingValue, \stdClass $response) { - if (is_object($response)) { - if ($response->HighestSeverity == 'FAILURE' || $response->HighestSeverity == 'ERROR') { - $errorTitle = (string)$response->Notifications->Message; - } elseif (isset($response->TrackDetails)) { - $trackInfo = $response->TrackDetails; - $resultArray['status'] = (string)$trackInfo->StatusDescription; - $resultArray['service'] = (string)$trackInfo->ServiceInfo; - $timestamp = isset( - $trackInfo->EstimatedDeliveryTimestamp - ) ? $trackInfo->EstimatedDeliveryTimestamp : $trackInfo->ActualDeliveryTimestamp; - $timestamp = strtotime((string)$timestamp); - if ($timestamp) { - $resultArray['deliverydate'] = date('Y-m-d', $timestamp); - $resultArray['deliverytime'] = date('H:i:s', $timestamp); - } - - $deliveryLocation = isset( - $trackInfo->EstimatedDeliveryAddress - ) ? $trackInfo->EstimatedDeliveryAddress : $trackInfo->ActualDeliveryAddress; - $deliveryLocationArray = []; - if (isset($deliveryLocation->City)) { - $deliveryLocationArray[] = (string)$deliveryLocation->City; - } - if (isset($deliveryLocation->StateOrProvinceCode)) { - $deliveryLocationArray[] = (string)$deliveryLocation->StateOrProvinceCode; - } - if (isset($deliveryLocation->CountryCode)) { - $deliveryLocationArray[] = (string)$deliveryLocation->CountryCode; - } - if ($deliveryLocationArray) { - $resultArray['deliverylocation'] = implode(', ', $deliveryLocationArray); - } - - $resultArray['signedby'] = (string)$trackInfo->DeliverySignatureName; - $resultArray['shippeddate'] = date('Y-m-d', (int)$trackInfo->ShipTimestamp); - if (isset($trackInfo->PackageWeight) && isset($trackInfo->Units)) { - $weight = (string)$trackInfo->PackageWeight; - $unit = (string)$trackInfo->Units; - $resultArray['weight'] = "{$weight} {$unit}"; - } - - $packageProgress = []; - if (isset($trackInfo->Events)) { - $events = $trackInfo->Events; - if (isset($events->Address)) { - $events = [$events]; - } - foreach ($events as $event) { - $tempArray = []; - $tempArray['activity'] = (string)$event->EventDescription; - $timestamp = strtotime((string)$event->Timestamp); - if ($timestamp) { - $tempArray['deliverydate'] = date('Y-m-d', $timestamp); - $tempArray['deliverytime'] = date('H:i:s', $timestamp); - } - if (isset($event->Address)) { - $addressArray = []; - $address = $event->Address; - if (isset($address->City)) { - $addressArray[] = (string)$address->City; - } - if (isset($address->StateOrProvinceCode)) { - $addressArray[] = (string)$address->StateOrProvinceCode; - } - if (isset($address->CountryCode)) { - $addressArray[] = (string)$address->CountryCode; - } - if ($addressArray) { - $tempArray['deliverylocation'] = implode(', ', $addressArray); - } - } - $packageProgress[] = $tempArray; - } - } - - $resultArray['progressdetail'] = $packageProgress; - } + if (in_array($response->HighestSeverity, self::$trackingErrors)) { + $this->appendTrackingError($trackingValue, (string) $response->Notifications->Message); + return; + } else if (empty($response->CompletedTrackDetails) || empty($response->CompletedTrackDetails->TrackDetails)) { + $this->appendTrackingError($trackingValue, __('No available tracking items')); + return; } - if (!$this->_result) { - $this->_result = $this->_trackFactory->create(); + $trackInfo = $response->CompletedTrackDetails->TrackDetails; + + // Fedex can return tracking details as single object instead array + if (is_object($trackInfo)) { + $trackInfo = [$trackInfo]; } - if (isset($resultArray)) { + $result = $this->getResult(); + $carrierTitle = $this->getConfigData('title'); + $counter = 0; + foreach ($trackInfo as $item) { $tracking = $this->_trackStatusFactory->create(); - $tracking->setCarrier('fedex'); - $tracking->setCarrierTitle($this->getConfigData('title')); + $tracking->setCarrier(self::CODE); + $tracking->setCarrierTitle($carrierTitle); $tracking->setTracking($trackingValue); - $tracking->addData($resultArray); - $this->_result->append($tracking); - } else { - $error = $this->_trackErrorFactory->create(); - $error->setCarrier('fedex'); - $error->setCarrierTitle($this->getConfigData('title')); - $error->setTracking($trackingValue); - $error->setErrorMessage( - $errorTitle ? $errorTitle : __('For some reason we can\'t retrieve tracking info right now.') + $tracking->addData($this->processTrackingDetails($item)); + $result->append($tracking); + $counter ++; + } + + // no available tracking details + if (!$counter) { + $this->appendTrackingError( + $trackingValue, __('For some reason we can\'t retrieve tracking info right now.') ); - $this->_result->append($error); } } @@ -1596,4 +1548,166 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C } return $data; } + + /** + * @param \stdClass $trackInfo + * @return array + */ + private function processTrackingDetails(\stdClass $trackInfo) + { + $result = [ + 'shippeddate' => null, + 'deliverydate' => null, + 'deliverytime' => null, + 'deliverylocation' => null, + 'weight' => null, + 'progressdetail' => [], + ]; + + if (!empty($trackInfo->ShipTimestamp)) { + $datetime = \DateTime::createFromFormat(\DateTime::ISO8601, $trackInfo->ShipTimestamp); + $result['shippeddate'] = $datetime->format('Y-m-d'); + } + + $result['signedby'] = !empty($trackInfo->DeliverySignatureName) ? + (string) $trackInfo->DeliverySignatureName : + null; + + $result['status'] = (!empty($trackInfo->StatusDetail) && !empty($trackInfo->StatusDetail->Description)) ? + (string) $trackInfo->StatusDetail->Description : + null; + $result['service'] = (!empty($trackInfo->Service) && !empty($trackInfo->Service->Description)) ? + (string) $trackInfo->Service->Description : + null; + + $datetime = $this->getDeliveryDateTime($trackInfo); + if ($datetime) { + $result['deliverydate'] = $datetime->format('Y-m-d'); + $result['deliverytime'] = $datetime->format('H:i:s'); + } + + $address = null; + if (!empty($trackInfo->EstimatedDeliveryAddress)) { + $address = $trackInfo->EstimatedDeliveryAddress; + } elseif (!empty($trackInfo->ActualDeliveryAddress)) { + $address = $trackInfo->ActualDeliveryAddress; + } + + if (!empty($address)) { + $result['deliverylocation'] = $this->getDeliveryAddress($address); + } + + if (!empty($trackInfo->PackageWeight)) { + $result['weight'] = sprintf( + '%s %s', + (string) $trackInfo->PackageWeight->Value, + (string) $trackInfo->PackageWeight->Units + ); + } + + if (!empty($trackInfo->Events)) { + $events = $trackInfo->Events; + if (is_object($events)) { + $events = [$trackInfo->Events]; + } + $result['progressdetail'] = $this->processTrackDetailsEvents($events); + } + + return $result; + } + + /** + * Parse delivery datetime from tracking details + * @param \stdClass $trackInfo + * @return \Datetime|null + */ + private function getDeliveryDateTime(\stdClass $trackInfo) + { + $timestamp = null; + if (!empty($trackInfo->EstimatedDeliveryTimestamp)) { + $timestamp = $trackInfo->EstimatedDeliveryTimestamp; + } elseif (!empty($trackInfo->ActualDeliveryTimestamp)) { + $timestamp = $trackInfo->ActualDeliveryTimestamp; + } + + return $timestamp ? \DateTime::createFromFormat(\DateTime::ISO8601, $timestamp) : null; + } + + /** + * Get delivery address details in string representation + * Return City, State, Country Code + * + * @param \stdClass $address + * @return \Magento\Framework\Phrase|string + */ + private function getDeliveryAddress(\stdClass $address) + { + $details = []; + + if (!empty($address->City)) { + $details[] = (string) $address->City; + } + + if (!empty($address->StateOrProvinceCode)) { + $details[] = (string) $address->StateOrProvinceCode; + } + + if (!empty($address->CountryCode)) { + $details[] = (string) $address->CountryCode; + } + + return implode(', ', $details); + } + + /** + * Parse tracking details events from response + * Return list of items in such format: + * ['activity', 'deliverydate', 'deliverytime', 'deliverylocation'] + * + * @param array $events + * @return array + */ + private function processTrackDetailsEvents(array $events) + { + $result = []; + /** @var \stdClass $event */ + foreach ($events as $event) { + $item = [ + 'activity' => (string) $event->EventDescription, + 'deliverydate' => null, + 'deliverytime' => null, + 'deliverylocation' => null + ]; + + if (!empty($event->Timestamp)) { + $datetime = \DateTime::createFromFormat(\DateTime::ISO8601, $event->Timestamp); + $item['deliverydate'] = $datetime->format('Y-m-d'); + $item['deliverytime'] = $datetime->format('H:i:s'); + } + + if (!empty($event->Address)) { + $item['deliverylocation'] = $this->getDeliveryAddress($event->Address); + } + + $result[] = $item; + } + + return $result; + } + + /** + * Append error message to rate result instance + * @param string $trackingValue + * @param string $errorMessage + */ + private function appendTrackingError($trackingValue, $errorMessage) + { + $error = $this->_trackErrorFactory->create(); + $error->setCarrier('fedex'); + $error->setCarrierTitle($this->getConfigData('title')); + $error->setTracking($trackingValue); + $error->setErrorMessage($errorMessage); + $result = $this->getResult(); + $result->append($error); + } } diff --git a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php index 702b6e69098..4a54993508c 100644 --- a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php @@ -5,167 +5,200 @@ */ namespace Magento\Fedex\Test\Unit\Model; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogInventory\Model\StockRegistry; +use Magento\Directory\Helper\Data; +use Magento\Directory\Model\Country; +use Magento\Directory\Model\CountryFactory; +use Magento\Directory\Model\CurrencyFactory; +use Magento\Directory\Model\RegionFactory; use Magento\Fedex\Model\Carrier; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Module\Dir\Reader; +use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\Xml\Security; use Magento\Quote\Model\Quote\Address\RateRequest; +use Magento\Quote\Model\Quote\Address\RateResult\Error as RateResultError; +use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory as RateErrorFactory; +use Magento\Quote\Model\Quote\Address\RateResult\Method; +use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; +use Magento\Shipping\Model\Rate\Result as RateResult; +use Magento\Shipping\Model\Rate\ResultFactory as RateResultFactory; +use Magento\Shipping\Model\Simplexml\ElementFactory; +use Magento\Shipping\Model\Tracking\Result; +use Magento\Shipping\Model\Tracking\Result\Error; +use Magento\Shipping\Model\Tracking\Result\ErrorFactory; +use Magento\Shipping\Model\Tracking\Result\Status; +use Magento\Shipping\Model\Tracking\Result\StatusFactory; +use Magento\Shipping\Model\Tracking\ResultFactory; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Psr\Log\LoggerInterface; /** - * Class CarrierTest - * @package Magento\Fedex\Model - * TODO refactor me + * CarrierTest contains units test for Fedex carrier methods * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CarrierTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + * @var ObjectManager */ - protected $_helper; + private $helper; /** - * @var \Magento\Fedex\Model\Carrier + * @var Carrier|MockObject */ - protected $_model; + private $model; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|MockObject */ - protected $scope; + private $scope; /** - * Model under test - * - * @var \Magento\Quote\Model\Quote\Address\RateResult\Error|\PHPUnit_Framework_MockObject_MockObject + * @var Error|MockObject */ - protected $error; + private $error; /** - * @var \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory|\PHPUnit_Framework_MockObject_MockObject + * @var ErrorFactory|MockObject */ - protected $errorFactory; + private $errorFactory; /** - * @return void + * @var ErrorFactory|MockObject + */ + private $trackErrorFactory; + + /** + * @var StatusFactory|MockObject + */ + private $statusFactory; + + /** + * @var Result + */ + private $result; + + /** + * @inheritdoc */ protected function setUp() { - $this->scope = $this->getMockBuilder( - \Magento\Framework\App\Config\ScopeConfigInterface::class - )->disableOriginalConstructor()->getMock(); - - $this->scope->expects($this->any())->method('getValue')->willReturnCallback([$this, 'scopeConfiggetValue']); - $country = $this->getMock( - \Magento\Directory\Model\Country::class, - ['load', 'getData', '__wakeup'], - [], - '', - false - ); - $country->expects($this->any())->method('load')->will($this->returnSelf()); - $countryFactory = $this->getMock(\Magento\Directory\Model\CountryFactory::class, ['create'], [], '', false); - $countryFactory->expects($this->any())->method('create')->will($this->returnValue($country)); - - $rate = $this->getMock(\Magento\Shipping\Model\Rate\Result::class, ['getError'], [], '', false); - $rateFactory = $this->getMock(\Magento\Shipping\Model\Rate\ResultFactory::class, ['create'], [], '', false); - $rateFactory->expects($this->any())->method('create')->will($this->returnValue($rate)); - $this->error = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\RateResult\Error::class) - ->setMethods(['setCarrier', 'setCarrierTitle', 'setErrorMessage'])->getMock(); - $this->errorFactory = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory::class) - ->disableOriginalConstructor()->setMethods(['create'])->getMock(); - $this->errorFactory->expects($this->any())->method('create')->willReturn($this->error); - - $store = $this->getMock(\Magento\Store\Model\Store::class, ['getBaseCurrencyCode', '__wakeup'], [], '', false); - $storeManager = $this->getMockForAbstractClass(\Magento\Store\Model\StoreManagerInterface::class); - $storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store)); - $priceCurrency = $this->getMockBuilder(\Magento\Framework\Pricing\PriceCurrencyInterface::class)->getMock(); - - $rateMethod = $this->getMock( - \Magento\Quote\Model\Quote\Address\RateResult\Method::class, - null, - ['priceCurrency' => $priceCurrency] - ); - $rateMethodFactory = $this->getMock( - \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory::class, - ['create'], - [], - '', - false - ); - $rateMethodFactory->expects($this->any())->method('create')->will($this->returnValue($rateMethod)); - $this->_model = $this->getMock( - \Magento\Fedex\Model\Carrier::class, - ['_getCachedQuotes', '_debug'], - [ - 'scopeConfig' => $this->scope, - 'rateErrorFactory' => $this->errorFactory, - 'logger' => $this->getMock(\Psr\Log\LoggerInterface::class), - 'xmlSecurity' => new Security(), - 'xmlElFactory' => $this->getMock( - \Magento\Shipping\Model\Simplexml\ElementFactory::class, - [], - [], - '', - false - ), - 'rateFactory' => $rateFactory, - 'rateMethodFactory' => $rateMethodFactory, - 'trackFactory' => $this->getMock( - \Magento\Shipping\Model\Tracking\ResultFactory::class, - [], - [], - '', - false - ), - 'trackErrorFactory' => $this->getMock(\Magento\Shipping\Model\Tracking\Result\ErrorFactory::class, [], [], '', false), - 'trackStatusFactory' => $this->getMock(\Magento\Shipping\Model\Tracking\Result\StatusFactory::class, [], [], '', false), - 'regionFactory' => $this->getMock(\Magento\Directory\Model\RegionFactory::class, [], [], '', false), - 'countryFactory' => $countryFactory, - 'currencyFactory' => $this->getMock(\Magento\Directory\Model\CurrencyFactory::class, [], [], '', false), - 'directoryData' => $this->getMock(\Magento\Directory\Helper\Data::class, [], [], '', false), - 'stockRegistry' => $this->getMock( - \Magento\CatalogInventory\Model\StockRegistry::class, - [], - [], - '', - false - ), - 'storeManager' => $storeManager, - 'configReader' => $this->getMock(\Magento\Framework\Module\Dir\Reader::class, [], [], '', false), - 'productCollectionFactory' => $this->getMock( - \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory::class, - [], - [], - '', - false - ), - 'data' => [], - ] - ); + $this->helper = new ObjectManager($this); + $this->scope = $this->getMockBuilder(ScopeConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->scope->expects(static::any()) + ->method('getValue') + ->willReturnCallback([$this, 'scopeConfigGetValue']); + + $countryFactory = $this->getCountryFactory(); + $rateFactory = $this->getRateFactory(); + $storeManager = $this->getStoreManager(); + $resultFactory = $this->getResultFactory(); + $this->initRateErrorFactory(); + + $rateMethodFactory = $this->getRateMethodFactory(); + + $this->trackErrorFactory = $this->getMockBuilder(ErrorFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->statusFactory = $this->getMockBuilder(StatusFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $elementFactory = $this->getMockBuilder(ElementFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $collectionFactory = $this->getMockBuilder(CollectionFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $regionFactory = $this->getMockBuilder(RegionFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $currencyFactory = $this->getMockBuilder(CurrencyFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $data = $this->getMockBuilder(Data::class) + ->disableOriginalConstructor() + ->getMock(); + + $stockRegistry = $this->getMockBuilder(StockRegistry::class) + ->disableOriginalConstructor() + ->getMock(); + + $reader = $this->getMockBuilder(Reader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = $this->getMockBuilder(Carrier::class) + ->setMethods(['_getCachedQuotes', '_debug']) + ->setConstructorArgs( + [ + 'scopeConfig' => $this->scope, + 'rateErrorFactory' => $this->errorFactory, + 'logger' => $this->getMock(LoggerInterface::class), + 'xmlSecurity' => new Security(), + 'xmlElFactory' => $elementFactory, + 'rateFactory' => $rateFactory, + 'rateMethodFactory' => $rateMethodFactory, + 'trackFactory' => $resultFactory, + 'trackErrorFactory' => $this->trackErrorFactory, + 'trackStatusFactory' => $this->statusFactory, + 'regionFactory' => $regionFactory, + 'countryFactory' => $countryFactory, + 'currencyFactory' => $currencyFactory, + 'directoryData' => $data, + 'stockRegistry' => $stockRegistry, + 'storeManager' => $storeManager, + 'configReader' => $reader, + 'productCollectionFactory' => $collectionFactory, + ] + ) + ->getMock(); } + /** + * @covers \Magento\Fedex\Model\Carrier::setRequest + */ public function testSetRequestWithoutCity() { - $requestMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\RateRequest::class) + $request = $this->getMockBuilder(RateRequest::class) ->disableOriginalConstructor() ->setMethods(['getDestCity']) ->getMock(); - $requestMock->expects($this->once()) + $request->expects($this->once()) ->method('getDestCity') ->willReturn(null); - $this->_model->setRequest($requestMock); + $this->model->setRequest($request); } + /** + * @covers \Magento\Fedex\Model\Carrier::setRequest + */ public function testSetRequestWithCity() { - $requestMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address\RateRequest::class) + $request = $this->getMockBuilder(RateRequest::class) ->disableOriginalConstructor() ->setMethods(['getDestCity']) ->getMock(); - $requestMock->expects($this->exactly(2)) + $request->expects(static::exactly(2)) ->method('getDestCity') ->willReturn('Small Town'); - $this->_model->setRequest($requestMock); + $this->model->setRequest($request); } /** @@ -173,7 +206,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase * @param $path * @return null|string */ - public function scopeConfiggetValue($path) + public function scopeConfigGetValue($path) { switch ($path) { case 'carriers/fedex/showmethod': @@ -183,53 +216,55 @@ class CarrierTest extends \PHPUnit_Framework_TestCase return 'ServiceType'; break; } + return null; } /** + * @param float $amount + * @param string $rateType + * @param float $expected * @dataProvider collectRatesDataProvider */ public function testCollectRatesRateAmountOriginBased($amount, $rateType, $expected) { - $this->scope->expects($this->any())->method('isSetFlag')->will($this->returnValue(true)); + $this->scope->expects(static::any()) + ->method('isSetFlag') + ->willReturn(true); - // @codingStandardsIgnoreStart - $netAmount = new \Magento\Framework\DataObject([]); + $netAmount = new \stdClass(); $netAmount->Amount = $amount; - $totalNetCharge = new \Magento\Framework\DataObject([]); + $totalNetCharge = new \stdClass(); $totalNetCharge->TotalNetCharge = $netAmount; $totalNetCharge->RateType = $rateType; - $ratedShipmentDetail = new \Magento\Framework\DataObject([]); + $ratedShipmentDetail = new \stdClass(); $ratedShipmentDetail->ShipmentRateDetail = $totalNetCharge; - $rate = new \Magento\Framework\DataObject([]); + $rate = new \stdClass(); $rate->ServiceType = 'ServiceType'; $rate->RatedShipmentDetails = [$ratedShipmentDetail]; - $response = new \Magento\Framework\DataObject([]); + $response = new \stdClass(); $response->HighestSeverity = 'SUCCESS'; $response->RateReplyDetails = $rate; - $this->_model->expects($this->any())->method('_getCachedQuotes')->will( - $this->returnValue(serialize($response)) - ); - $request = $this->getMock( - \Magento\Quote\Model\Quote\Address\RateRequest::class, - ['getDestCity'], - [], - '', - false - ); - $request->expects($this->exactly(2)) - ->method('getDestCity') - ->willReturn('Wonderful City'); - foreach ($this->_model->collectRates($request)->getAllRates() as $allRates) { + $this->model->expects(static::any()) + ->method('_getCachedQuotes') + ->willReturn(serialize($response)); + $request = $this->getMockBuilder(RateRequest::class) + ->disableOriginalConstructor() + ->getMock(); + + foreach ($this->model->collectRates($request)->getAllRates() as $allRates) { $this->assertEquals($expected, $allRates->getData('cost')); } - // @codingStandardsIgnoreEnd } + /** + * Get list of rates variations + * @return array + */ public function collectRatesDataProvider() { return [ @@ -246,16 +281,22 @@ class CarrierTest extends \PHPUnit_Framework_TestCase public function testCollectRatesErrorMessage() { - $this->scope->expects($this->once())->method('isSetFlag')->willReturn(false); + $this->scope->expects(static::once()) + ->method('isSetFlag') + ->willReturn(false); - $this->error->expects($this->once())->method('setCarrier')->with('fedex'); - $this->error->expects($this->once())->method('setCarrierTitle'); - $this->error->expects($this->once())->method('setErrorMessage'); + $this->error->expects(static::once()) + ->method('setCarrier') + ->with('fedex'); + $this->error->expects(static::once()) + ->method('setCarrierTitle'); + $this->error->expects(static::once()) + ->method('setErrorMessage'); $request = new RateRequest(); $request->setPackageWeight(1); - $this->assertSame($this->error, $this->_model->collectRates($request)); + static::assertSame($this->error, $this->model->collectRates($request)); } /** @@ -269,11 +310,11 @@ class CarrierTest extends \PHPUnit_Framework_TestCase $refClass = new \ReflectionClass(Carrier::class); $property = $refClass->getProperty('_debugReplacePrivateDataKeys'); $property->setAccessible(true); - $property->setValue($this->_model, $maskFields); + $property->setValue($this->model, $maskFields); $refMethod = $refClass->getMethod('filterDebugData'); $refMethod->setAccessible(true); - $result = $refMethod->invoke($this->_model, $data); + $result = $refMethod->invoke($this->model, $data); static::assertEquals($expected, $result); } @@ -312,4 +353,277 @@ class CarrierTest extends \PHPUnit_Framework_TestCase ], ]; } + + /** + * @covers \Magento\Fedex\Model\Carrier::getTracking + */ + public function testGetTrackingErrorResponse() + { + $tracking = '123456789012'; + $errorMessage = 'Tracking information is unavailable.'; + + $response = new \stdClass(); + $response->HighestSeverity = 'ERROR'; + $response->Notifications = new \stdClass(); + $response->Notifications->Message = $errorMessage; + + $this->model->expects(static::once()) + ->method('_getCachedQuotes') + ->willReturn(serialize($response)); + + $error = $this->helper->getObject(Error::class); + $this->trackErrorFactory->expects(static::once()) + ->method('create') + ->willReturn($error); + + $this->model->getTracking($tracking); + $tracks = $this->model->getResult()->getAllTrackings(); + + static::assertEquals(1, count($tracks)); + + /** @var Error $current */ + $current = $tracks[0]; + static::assertInstanceOf(Error::class, $current); + static::assertEquals(__($errorMessage), $current->getErrorMessage()); + } + + /** + * @covers \Magento\Fedex\Model\Carrier::getTracking + */ + public function testGetTracking() + { + $tracking = '123456789012'; + + $response = new \stdClass(); + $response->HighestSeverity = 'SUCCESS'; + $response->CompletedTrackDetails = new \stdClass(); + + $trackDetails = new \stdClass(); + $trackDetails->ShipTimestamp = '2016-08-05T14:06:35+00:00'; + $trackDetails->DeliverySignatureName = 'signature'; + + $trackDetails->StatusDetail = new \stdClass(); + $trackDetails->StatusDetail->Description = 'SUCCESS'; + + $trackDetails->Service = new \stdClass(); + $trackDetails->Service->Description = 'ground'; + $trackDetails->EstimatedDeliveryTimestamp = '2016-08-10T10:20:26+00:00'; + + $trackDetails->EstimatedDeliveryAddress = new \stdClass(); + $trackDetails->EstimatedDeliveryAddress->City = 'Culver City'; + $trackDetails->EstimatedDeliveryAddress->StateOrProvinceCode = 'CA'; + $trackDetails->EstimatedDeliveryAddress->CountryCode = 'US'; + + $trackDetails->PackageWeight = new \stdClass(); + $trackDetails->PackageWeight->Value = 23; + $trackDetails->PackageWeight->Units = 'LB'; + + $response->CompletedTrackDetails->TrackDetails = [$trackDetails]; + + $this->model->expects(static::once()) + ->method('_getCachedQuotes') + ->willReturn(serialize($response)); + + $status = $this->helper->getObject(Status::class); + $this->statusFactory->expects(static::once()) + ->method('create') + ->willReturn($status); + + $this->model->getTracking($tracking); + $tracks = $this->model->getResult()->getAllTrackings(); + static::assertEquals(1, count($tracks)); + + $current = $tracks[0]; + $fields = [ + 'signedby', + 'status', + 'service', + 'shippeddate', + 'deliverydate', + 'deliverytime', + 'deliverylocation', + 'weight', + ]; + array_walk($fields, function ($field) use ($current) { + static::assertNotEmpty($current[$field]); + }); + + static::assertEquals('2016-08-10', $current['deliverydate']); + static::assertEquals('10:20:26', $current['deliverytime']); + static::assertEquals('2016-08-05', $current['shippeddate']); + } + + /** + * @covers \Magento\Fedex\Model\Carrier::getTracking + */ + public function testGetTrackingWithEvents() + { + $tracking = '123456789012'; + + $response = new \stdClass(); + $response->HighestSeverity = 'SUCCESS'; + $response->CompletedTrackDetails = new \stdClass(); + + $event = new \stdClass(); + $event->EventDescription = 'Test'; + $event->Timestamp = '2016-08-05T19:14:53+00:00'; + $event->Address = new \stdClass(); + + $event->Address->City = 'Culver City'; + $event->Address->StateOrProvinceCode = 'CA'; + $event->Address->CountryCode = 'US'; + + $trackDetails = new \stdClass(); + $trackDetails->Events = $event; + + $response->CompletedTrackDetails->TrackDetails = $trackDetails; + + $this->model->expects(static::once()) + ->method('_getCachedQuotes') + ->willReturn(serialize($response)); + + $status = $this->helper->getObject(Status::class); + $this->statusFactory->expects(static::once()) + ->method('create') + ->willReturn($status); + + $this->model->getTracking($tracking); + $tracks = $this->model->getResult()->getAllTrackings(); + static::assertEquals(1, count($tracks)); + + $current = $tracks[0]; + static::assertNotEmpty($current['progressdetail']); + static::assertEquals(1, count($current['progressdetail'])); + + $event = $current['progressdetail'][0]; + $fields = ['activity', 'deliverydate', 'deliverytime', 'deliverylocation']; + array_walk($fields, function ($field) use ($event) { + static::assertNotEmpty($event[$field]); + }); + static::assertEquals('2016-08-05', $event['deliverydate']); + static::assertEquals('19:14:53', $event['deliverytime']); + } + + /** + * Init RateErrorFactory and RateResultErrors mocks + * @return void + */ + private function initRateErrorFactory() + { + $this->error = $this->getMockBuilder(RateResultError::class) + ->disableOriginalConstructor() + ->setMethods(['setCarrier', 'setCarrierTitle', 'setErrorMessage']) + ->getMock(); + $this->errorFactory = $this->getMockBuilder(RateErrorFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->errorFactory->expects(static::any()) + ->method('create') + ->willReturn($this->error); + } + + /** + * Creates mock rate result factory + * @return RateResultFactory|MockObject + */ + private function getRateFactory() + { + $rate = $this->getMockBuilder(RateResult::class) + ->disableOriginalConstructor() + ->setMethods(['getError']) + ->getMock(); + $rateFactory = $this->getMockBuilder(RateResultFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $rateFactory->expects(static::any()) + ->method('create') + ->willReturn($rate); + + return $rateFactory; + } + + /** + * Creates mock object for CountryFactory class + * @return CountryFactory|MockObject + */ + private function getCountryFactory() + { + $country = $this->getMockBuilder(Country::class) + ->disableOriginalConstructor() + ->setMethods(['load', 'getData']) + ->getMock(); + $country->expects(static::any()) + ->method('load') + ->willReturnSelf(); + + $countryFactory = $this->getMockBuilder(CountryFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $countryFactory->expects(static::any()) + ->method('create') + ->willReturn($country); + + return $countryFactory; + } + + /** + * Creates mock object for ResultFactory class + * @return ResultFactory|MockObject + */ + private function getResultFactory() + { + $resultFactory = $this->getMockBuilder(ResultFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->result = $this->helper->getObject(Result::class); + $resultFactory->expects(static::any()) + ->method('create') + ->willReturn($this->result); + + return $resultFactory; + } + + /** + * Creates mock object for store manager + * @return StoreManagerInterface|MockObject + */ + private function getStoreManager() + { + $store = $this->getMockBuilder(Store::class) + ->disableOriginalConstructor() + ->setMethods(['getBaseCurrencyCode']) + ->getMock(); + $storeManager = $this->getMock(StoreManagerInterface::class); + $storeManager->expects(static::any()) + ->method('getStore') + ->willReturn($store); + + return $storeManager; + } + + /** + * Creates mock object for rate method factory + * @return MethodFactory|MockObject + */ + private function getRateMethodFactory() + { + $priceCurrency = $this->getMock(PriceCurrencyInterface::class); + $rateMethod = $this->getMockBuilder(Method::class) + ->setConstructorArgs(['priceCurrency' => $priceCurrency]) + ->setMethods(null) + ->getMock(); + $rateMethodFactory = $this->getMockBuilder(MethodFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $rateMethodFactory->expects(static::any()) + ->method('create') + ->willReturn($rateMethod); + + return $rateMethodFactory; + } } diff --git a/app/code/Magento/Fedex/etc/wsdl/TrackService_v5.wsdl b/app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl similarity index 63% rename from app/code/Magento/Fedex/etc/wsdl/TrackService_v5.wsdl rename to app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl index f3ceaf5056a..3771c1e6978 100644 --- a/app/code/Magento/Fedex/etc/wsdl/TrackService_v5.wsdl +++ b/app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl @@ -1,12 +1,12 @@ -<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://fedex.com/ws/track/v5" xmlns:s1="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://fedex.com/ws/track/v5" name="TrackServiceDefinitions"> +<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://fedex.com/ws/track/v10" xmlns:s1="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://fedex.com/ws/track/v10" name="TrackServiceDefinitions"> <types> - <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://fedex.com/ws/track/v5"> + <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://fedex.com/ws/track/v10"> + <xs:element name="SendNotificationsReply" type="ns:SendNotificationsReply"/> + <xs:element name="SendNotificationsRequest" type="ns:SendNotificationsRequest"/> <xs:element name="SignatureProofOfDeliveryFaxReply" type="ns:SignatureProofOfDeliveryFaxReply"/> <xs:element name="SignatureProofOfDeliveryFaxRequest" type="ns:SignatureProofOfDeliveryFaxRequest"/> <xs:element name="SignatureProofOfDeliveryLetterReply" type="ns:SignatureProofOfDeliveryLetterReply"/> <xs:element name="SignatureProofOfDeliveryLetterRequest" type="ns:SignatureProofOfDeliveryLetterRequest"/> - <xs:element name="TrackNotificationReply" type="ns:TrackNotificationReply"/> - <xs:element name="TrackNotificationRequest" type="ns:TrackNotificationRequest"/> <xs:element name="TrackReply" type="ns:TrackReply"/> <xs:element name="TrackRequest" type="ns:TrackRequest"/> <xs:complexType name="Address"> @@ -14,7 +14,7 @@ <xs:documentation>Descriptive data for a physical location. May be used as an actual physical address (place to which one could go), or as a container of "address parts" which should be handled as a unit (such as a city-state-ZIP combination within the US).</xs:documentation> </xs:annotation> <xs:sequence> - <xs:element name="StreetLines" type="xs:string" minOccurs="0" maxOccurs="2"> + <xs:element name="StreetLines" type="xs:string" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>Combination of number, street name, etc. At least one line is required for a valid physical address; empty lines should not be included.</xs:documentation> </xs:annotation> @@ -44,6 +44,11 @@ <xs:documentation>The two-letter code used to identify a country.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="CountryName" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>The fully spelt out name of a country.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="Residential" type="xs:boolean" minOccurs="0"> <xs:annotation> <xs:documentation>Indicates whether this address residential (as opposed to commercial).</xs:documentation> @@ -51,6 +56,48 @@ </xs:element> </xs:sequence> </xs:complexType> + <xs:complexType name="AppointmentDetail"> + <xs:annotation> + <xs:documentation>Specifies the different appointment times on a specific date.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Date" type="xs:date" minOccurs="0"/> + <xs:element name="WindowDetails" type="ns:AppointmentTimeDetail" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Different appointment time windows on the date specified.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="AppointmentTimeDetail"> + <xs:annotation> + <xs:documentation>Specifies the details about the appointment time window.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Type" type="ns:AppointmentWindowType" minOccurs="0"> + <xs:annotation> + <xs:documentation>The description that FedEx Ground uses for the appointment window being specified.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Window" type="ns:LocalTimeRange" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the window of time for an appointment.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="AppointmentWindowType"> + <xs:annotation> + <xs:documentation>The description that FedEx uses for a given appointment window.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="AFTERNOON"/> + <xs:enumeration value="LATE_AFTERNOON"/> + <xs:enumeration value="MID_DAY"/> + <xs:enumeration value="MORNING"/> + </xs:restriction> + </xs:simpleType> <xs:simpleType name="ArrivalLocationType"> <xs:annotation> <xs:documentation>Identifies where a tracking event occurs.</xs:documentation> @@ -73,11 +120,18 @@ <xs:enumeration value="PICKUP_LOCATION"/> <xs:enumeration value="PLANE"/> <xs:enumeration value="PORT_OF_ENTRY"/> + <xs:enumeration value="SHIP_AND_GET_LOCATION"/> <xs:enumeration value="SORT_FACILITY"/> <xs:enumeration value="TURNPOINT"/> <xs:enumeration value="VEHICLE"/> </xs:restriction> </xs:simpleType> + <xs:simpleType name="AvailableImageType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="BILL_OF_LADING"/> + <xs:enumeration value="SIGNATURE_PROOF_OF_DELIVERY"/> + </xs:restriction> + </xs:simpleType> <xs:simpleType name="CarrierCodeType"> <xs:annotation> <xs:documentation>Identification of a FedEx operating company (transportation).</xs:documentation> @@ -108,7 +162,7 @@ </xs:element> <xs:element name="IntegratorId" type="xs:string" minOccurs="0"> <xs:annotation> - <xs:documentation>Only used in transactions which require identification of the Fed Ex Office integrator.</xs:documentation> + <xs:documentation>Only used in transactions which require identification of the FedEx Office integrator.</xs:documentation> </xs:annotation> </xs:element> <xs:element name="Localization" type="ns:Localization" minOccurs="0"> @@ -118,6 +172,79 @@ </xs:element> </xs:sequence> </xs:complexType> + <xs:complexType name="Commodity"> + <xs:sequence> + <xs:element name="CommodityId" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Value used to identify a commodity description; must be unique within the containing shipment.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Name" type="xs:string" minOccurs="0"/> + <xs:element name="NumberOfPieces" type="xs:nonNegativeInteger" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + <xs:element name="CountryOfManufacture" type="xs:string" minOccurs="0"/> + <xs:element name="HarmonizedCode" type="xs:string" minOccurs="0"/> + <xs:element name="Weight" type="ns:Weight" minOccurs="0"/> + <xs:element name="Quantity" type="xs:decimal" minOccurs="0"> + <xs:annotation> + <xs:documentation>This field is used for enterprise transactions.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="QuantityUnits" type="xs:string" minOccurs="0"/> + <xs:element name="AdditionalMeasures" type="ns:Measure" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Contains only additional quantitative information other than weight and quantity to calculate duties and taxes.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="UnitPrice" type="ns:Money" minOccurs="0"/> + <xs:element name="CustomsValue" type="ns:Money" minOccurs="0"/> + <xs:element name="ExciseConditions" type="ns:EdtExciseCondition" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Defines additional characteristic of commodity used to calculate duties and taxes</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ExportLicenseNumber" type="xs:string" minOccurs="0"/> + <xs:element name="ExportLicenseExpirationDate" type="xs:date" minOccurs="0"/> + <xs:element name="CIMarksAndNumbers" type="xs:string" minOccurs="0"/> + <xs:element name="PartNumber" type="xs:string" minOccurs="0"/> + <xs:element name="NaftaDetail" type="ns:NaftaCommodityDetail" minOccurs="0"> + <xs:annotation> + <xs:documentation>All data required for this commodity in NAFTA Certificate of Origin.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="CompletedTrackDetail"> + <xs:sequence> + <xs:element name="HighestSeverity" type="ns:NotificationSeverityType" minOccurs="0"/> + <xs:element name="Notifications" type="ns:Notification" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="DuplicateWaybill" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:documentation>True if duplicate packages (more than one package with the same tracking number) have been found, and only limited data will be provided for each one.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MoreData" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:documentation>True if additional packages remain to be retrieved.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="PagingToken" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Value that must be passed in a TrackNotification request to retrieve the next set of packages (when MoreDataAvailable = true).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TrackDetailsCount" type="xs:nonNegativeInteger" minOccurs="0"> + <xs:annotation> + <xs:documentation>Identifies the total number of available track details across all pages.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TrackDetails" type="ns:TrackDetail" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Contains detailed tracking information for the requested packages(s).</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> <xs:complexType name="Contact"> <xs:annotation> <xs:documentation>The descriptive data for a point-of-contact person.</xs:documentation> @@ -148,6 +275,11 @@ <xs:documentation>Identifies the phone extension associated with this contact.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="TollFreePhoneNumber" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Identifies a toll free number, if any, associated with this contact.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="PagerNumber" type="xs:string" minOccurs="0"> <xs:annotation> <xs:documentation>Identifies the pager number associated with this contact.</xs:documentation> @@ -171,6 +303,84 @@ <xs:element name="Address" type="ns:Address" minOccurs="0"/> </xs:sequence> </xs:complexType> + <xs:complexType name="ContentRecord"> + <xs:sequence> + <xs:element name="PartNumber" type="xs:string" minOccurs="0"/> + <xs:element name="ItemNumber" type="xs:string" minOccurs="0"/> + <xs:element name="ReceivedQuantity" type="xs:nonNegativeInteger" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="CustomerExceptionRequestDetail"> + <xs:sequence> + <xs:element name="Id" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Unique identifier for the customer exception request.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="StatusCode" type="xs:string" minOccurs="0"/> + <xs:element name="StatusDescription" type="xs:string" minOccurs="0"/> + <xs:element name="CreateTime" type="xs:dateTime" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="CustomsOptionDetail"> + <xs:sequence> + <xs:element name="Type" type="ns:CustomsOptionType" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies additional description about customs options. This is a required field when the customs options type is "OTHER".</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="CustomsOptionType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="COURTESY_RETURN_LABEL"/> + <xs:enumeration value="EXHIBITION_TRADE_SHOW"/> + <xs:enumeration value="FAULTY_ITEM"/> + <xs:enumeration value="FOLLOWING_REPAIR"/> + <xs:enumeration value="FOR_REPAIR"/> + <xs:enumeration value="ITEM_FOR_LOAN"/> + <xs:enumeration value="OTHER"/> + <xs:enumeration value="REJECTED"/> + <xs:enumeration value="REPLACEMENT"/> + <xs:enumeration value="TRIAL"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="DateRange"> + <xs:sequence> + <xs:element name="Begins" type="xs:date" minOccurs="0"/> + <xs:element name="Ends" type="xs:date" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="DeliveryOptionEligibilityDetail"> + <xs:annotation> + <xs:documentation>Details about the eligibility for a delivery option.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Option" type="ns:DeliveryOptionType" minOccurs="0"> + <xs:annotation> + <xs:documentation>Type of delivery option.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Eligibility" type="ns:EligibilityType" minOccurs="0"> + <xs:annotation> + <xs:documentation>Eligibility of the customer for the specific delivery option.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="DeliveryOptionType"> + <xs:annotation> + <xs:documentation>Specifies the different option types for delivery.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="INDIRECT_SIGNATURE_RELEASE"/> + <xs:enumeration value="REDIRECT_TO_HOLD_AT_LOCATION"/> + <xs:enumeration value="REROUTE"/> + <xs:enumeration value="RESCHEDULE"/> + </xs:restriction> + </xs:simpleType> <xs:complexType name="Dimensions"> <xs:annotation> <xs:documentation>The dimensions of this package and the unit type used for the measurements.</xs:documentation> @@ -280,6 +490,43 @@ <xs:enumeration value="SHIPPER"/> </xs:restriction> </xs:simpleType> + <xs:complexType name="EdtExciseCondition"> + <xs:sequence> + <xs:element name="Category" type="xs:string" minOccurs="0"/> + <xs:element name="Value" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Customer-declared value, with data type and legal values depending on excise condition, used in defining the taxable value of the item.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="EligibilityType"> + <xs:annotation> + <xs:documentation>Specifies different values of eligibility status</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="ELIGIBLE"/> + <xs:enumeration value="INELIGIBLE"/> + <xs:enumeration value="POSSIBLY_ELIGIBLE"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="FedExLocationType"> + <xs:annotation> + <xs:documentation>Identifies a kind of FedEx facility.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="FEDEX_AUTHORIZED_SHIP_CENTER"/> + <xs:enumeration value="FEDEX_EXPRESS_STATION"/> + <xs:enumeration value="FEDEX_FACILITY"/> + <xs:enumeration value="FEDEX_FREIGHT_SERVICE_CENTER"/> + <xs:enumeration value="FEDEX_GROUND_TERMINAL"/> + <xs:enumeration value="FEDEX_HOME_DELIVERY_STATION"/> + <xs:enumeration value="FEDEX_OFFICE"/> + <xs:enumeration value="FEDEX_SELF_SERVICE_LOCATION"/> + <xs:enumeration value="FEDEX_SHIPSITE"/> + <xs:enumeration value="FEDEX_SMART_POST_HUB"/> + </xs:restriction> + </xs:simpleType> <xs:simpleType name="LinearUnits"> <xs:annotation> <xs:documentation>CM = centimeters, IN = inches</xs:documentation> @@ -289,6 +536,15 @@ <xs:enumeration value="IN"/> </xs:restriction> </xs:simpleType> + <xs:complexType name="LocalTimeRange"> + <xs:annotation> + <xs:documentation>Time Range specified in local time.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="Begins" type="xs:string" minOccurs="0"/> + <xs:element name="Ends" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> <xs:complexType name="Localization"> <xs:annotation> <xs:documentation>Identifies the representation of human-readable text.</xs:documentation> @@ -306,6 +562,73 @@ </xs:element> </xs:sequence> </xs:complexType> + <xs:complexType name="Measure"> + <xs:sequence> + <xs:element name="Quantity" type="xs:decimal" minOccurs="0"/> + <xs:element name="Units" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="Money"> + <xs:sequence> + <xs:element name="Currency" type="xs:string" minOccurs="0"/> + <xs:element name="Amount" type="xs:decimal" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="NaftaCommodityDetail"> + <xs:sequence> + <xs:element name="PreferenceCriterion" type="ns:NaftaPreferenceCriterionCode" minOccurs="0"> + <xs:annotation> + <xs:documentation>Defined by NAFTA regulations.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ProducerDetermination" type="ns:NaftaProducerDeterminationCode" minOccurs="0"> + <xs:annotation> + <xs:documentation>Defined by NAFTA regulations.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ProducerId" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Identification of which producer is associated with this commodity (if multiple producers are used in a single shipment).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NetCostMethod" type="ns:NaftaNetCostMethodCode" minOccurs="0"/> + <xs:element name="NetCostDateRange" type="ns:DateRange" minOccurs="0"> + <xs:annotation> + <xs:documentation>Date range over which RVC net cost was calculated.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="NaftaNetCostMethodCode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="NC"/> + <xs:enumeration value="NO"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NaftaPreferenceCriterionCode"> + <xs:annotation> + <xs:documentation>See instructions for NAFTA Certificate of Origin for code definitions.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="A"/> + <xs:enumeration value="B"/> + <xs:enumeration value="C"/> + <xs:enumeration value="D"/> + <xs:enumeration value="E"/> + <xs:enumeration value="F"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="NaftaProducerDeterminationCode"> + <xs:annotation> + <xs:documentation>See instructions for NAFTA Certificate of Origin for code definitions.</xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:enumeration value="NO_1"/> + <xs:enumeration value="NO_2"/> + <xs:enumeration value="NO_3"/> + <xs:enumeration value="YES"/> + </xs:restriction> + </xs:simpleType> <xs:complexType name="Notification"> <xs:annotation> <xs:documentation>The descriptive data regarding the result of the submitted transaction.</xs:documentation> @@ -382,7 +705,18 @@ <xs:documentation>Identification for a FedEx operating company (transportation and non-transportation).</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> + <xs:enumeration value="FEDEX_CARGO"/> + <xs:enumeration value="FEDEX_CORPORATE_SERVICES"/> + <xs:enumeration value="FEDEX_CORPORATION"/> + <xs:enumeration value="FEDEX_CUSTOMER_INFORMATION_SYSTEMS"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL"/> + <xs:enumeration value="FEDEX_EXPRESS"/> + <xs:enumeration value="FEDEX_FREIGHT"/> + <xs:enumeration value="FEDEX_GROUND"/> + <xs:enumeration value="FEDEX_KINKOS"/> <xs:enumeration value="FEDEX_OFFICE"/> + <xs:enumeration value="FEDEX_SERVICES"/> + <xs:enumeration value="FEDEX_TRADE_NETWORKS"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="PackagingType"> @@ -394,11 +728,42 @@ <xs:enumeration value="FEDEX_25KG_BOX"/> <xs:enumeration value="FEDEX_BOX"/> <xs:enumeration value="FEDEX_ENVELOPE"/> + <xs:enumeration value="FEDEX_EXTRA_LARGE_BOX"/> + <xs:enumeration value="FEDEX_LARGE_BOX"/> + <xs:enumeration value="FEDEX_MEDIUM_BOX"/> <xs:enumeration value="FEDEX_PAK"/> + <xs:enumeration value="FEDEX_SMALL_BOX"/> <xs:enumeration value="FEDEX_TUBE"/> <xs:enumeration value="YOUR_PACKAGING"/> </xs:restriction> </xs:simpleType> + <xs:complexType name="PagingDetail"> + <xs:sequence> + <xs:element name="PagingToken" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>When the MoreData field = true in a TrackReply the PagingToken must be sent in the subsequent TrackRequest to retrieve the next page of data.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NumberOfResultsPerPage" type="xs:nonNegativeInteger" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the number of results to display per page when the there is more than one page in the subsequent TrackReply.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="PieceCountLocationType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="DESTINATION"/> + <xs:enumeration value="ORIGIN"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="PieceCountVerificationDetail"> + <xs:sequence> + <xs:element name="CountLocationType" type="ns:PieceCountLocationType" minOccurs="0"/> + <xs:element name="Count" type="xs:nonNegativeInteger" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> <xs:complexType name="QualifiedTrackingNumber"> <xs:annotation> <xs:documentation>Tracking number and additional shipment data used to identify a unique shipment for proof of delivery.</xs:documentation> @@ -431,13 +796,115 @@ </xs:element> </xs:sequence> </xs:complexType> - <xs:simpleType name="RedirectToHoldEligibilityType"> - <xs:restriction base="xs:string"> - <xs:enumeration value="ELIGIBLE"/> - <xs:enumeration value="INELIGIBLE"/> - <xs:enumeration value="POSSIBLY_ELIGIBLE"/> - </xs:restriction> - </xs:simpleType> + <xs:complexType name="SendNotificationsReply"> + <xs:sequence> + <xs:element name="HighestSeverity" type="ns:NotificationSeverityType" minOccurs="1"> + <xs:annotation> + <xs:documentation>This contains the severity type of the most severe Notification in the Notifications array.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Notifications" type="ns:Notification" minOccurs="1" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Information about the request/reply such was the transaction successful or not, and any additional information relevant to the request and/or reply. There may be multiple Notifications in a reply.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TransactionDetail" type="ns:TransactionDetail" minOccurs="0"> + <xs:annotation> + <xs:documentation>Contains the CustomerTransactionDetail that is echoed back to the caller for matching requests and replies and a Localization element for defining the language/translation used in the reply data.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" type="ns:VersionId" minOccurs="1"> + <xs:annotation> + <xs:documentation>Contains the version of the reply being used.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DuplicateWaybill" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:documentation>True if duplicate packages (more than one package with the same tracking number) have been found, the packages array contains information about each duplicate. Use this information to determine which of the tracking numbers is the one you need and resend your request using the tracking number and TrackingNumberUniqueIdentifier for that package.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MoreDataAvailable" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:documentation>True if additional packages remain to be retrieved.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="PagingToken" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Value that must be passed in a TrackNotification request to retrieve the next set of packages (when MoreDataAvailable = true).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Packages" type="ns:TrackNotificationPackage" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Information about the notifications that are available for this tracking number. If there are duplicates the ship date and destination address information is returned for determining which TrackingNumberUniqueIdentifier to use on a subsequent request.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="SendNotificationsRequest"> + <xs:sequence> + <xs:element name="WebAuthenticationDetail" type="ns:WebAuthenticationDetail" minOccurs="1"> + <xs:annotation> + <xs:documentation>Descriptive data to be used in authentication of the sender's identity (and right to use FedEx web services).</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ClientDetail" type="ns:ClientDetail" minOccurs="1"> + <xs:annotation> + <xs:documentation>Descriptive data identifying the client submitting the transaction.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TransactionDetail" type="ns:TransactionDetail" minOccurs="0"> + <xs:annotation> + <xs:documentation>Contains a free form field that is echoed back in the reply to match requests with replies and data that governs the data payload language/translations</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Version" type="ns:VersionId" minOccurs="1"/> + <xs:element name="TrackingNumber" type="xs:string" minOccurs="1"> + <xs:annotation> + <xs:documentation>The tracking number to which the notifications will be triggered from.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="MultiPiece" type="xs:boolean" minOccurs="0"> + <xs:annotation> + <xs:documentation>Indicates whether to return tracking information for all associated packages.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="PagingToken" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>When the MoreDataAvailable field is true in a TrackNotificationReply the PagingToken must be sent in the subsequent TrackNotificationRequest to retrieve the next page of data.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TrackingNumberUniqueId" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Use this field when your original request informs you that there are duplicates of this tracking number. If you get duplicates you will also receive some information about each of the duplicate tracking numbers to enable you to chose one and resend that number along with the TrackingNumberUniqueId to get notifications for that tracking number.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ShipDateRangeBegin" type="xs:date" minOccurs="0"> + <xs:annotation> + <xs:documentation>To narrow the search to a period in time the ShipDateRangeBegin and ShipDateRangeEnd can be used to help eliminate duplicates.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ShipDateRangeEnd" type="xs:date" minOccurs="0"> + <xs:annotation> + <xs:documentation>To narrow the search to a period in time the ShipDateRangeBegin and ShipDateRangeEnd can be used to help eliminate duplicates.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SenderEMailAddress" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Included in the email notification identifying the requester of this notification.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="SenderContactName" type="xs:string" minOccurs="1"> + <xs:annotation> + <xs:documentation>Included in the email notification identifying the requester of this notification.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NotificationDetail" type="ns:EMailNotificationDetail" minOccurs="1"> + <xs:annotation> + <xs:documentation>Who to send the email notifications to and for which events. The notificationRecipientType and NotifyOnShipment fields are not used in this request.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> <xs:simpleType name="ServiceType"> <xs:annotation> <xs:documentation>The service type of the package/shipment.</xs:documentation> @@ -449,11 +916,34 @@ <xs:enumeration value="FEDEX_2_DAY_AM"/> <xs:enumeration value="FEDEX_2_DAY_FREIGHT"/> <xs:enumeration value="FEDEX_3_DAY_FREIGHT"/> + <xs:enumeration value="FEDEX_CARGO_AIRPORT_TO_AIRPORT"/> + <xs:enumeration value="FEDEX_CARGO_FREIGHT_FORWARDING"/> + <xs:enumeration value="FEDEX_CARGO_INTERNATIONAL_EXPRESS_FREIGHT"/> + <xs:enumeration value="FEDEX_CARGO_INTERNATIONAL_PREMIUM"/> + <xs:enumeration value="FEDEX_CARGO_MAIL"/> + <xs:enumeration value="FEDEX_CARGO_REGISTERED_MAIL"/> + <xs:enumeration value="FEDEX_CARGO_SURFACE_MAIL"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_AIR_EXPEDITE"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_AIR_EXPEDITE_EXCLUSIVE_USE"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_AIR_EXPEDITE_NETWORK"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_CHARTER_AIR"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_POINT_TO_POINT"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_SURFACE_EXPEDITE"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_SURFACE_EXPEDITE_EXCLUSIVE_USE"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_TEMP_ASSURE_AIR"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_TEMP_ASSURE_VALIDATED_AIR"/> + <xs:enumeration value="FEDEX_CUSTOM_CRITICAL_WHITE_GLOVE_SERVICES"/> + <xs:enumeration value="FEDEX_DISTANCE_DEFERRED"/> <xs:enumeration value="FEDEX_EXPRESS_SAVER"/> <xs:enumeration value="FEDEX_FIRST_FREIGHT"/> <xs:enumeration value="FEDEX_FREIGHT_ECONOMY"/> <xs:enumeration value="FEDEX_FREIGHT_PRIORITY"/> <xs:enumeration value="FEDEX_GROUND"/> + <xs:enumeration value="FEDEX_NEXT_DAY_AFTERNOON"/> + <xs:enumeration value="FEDEX_NEXT_DAY_EARLY_MORNING"/> + <xs:enumeration value="FEDEX_NEXT_DAY_END_OF_DAY"/> + <xs:enumeration value="FEDEX_NEXT_DAY_FREIGHT"/> + <xs:enumeration value="FEDEX_NEXT_DAY_MID_MORNING"/> <xs:enumeration value="FIRST_OVERNIGHT"/> <xs:enumeration value="GROUND_HOME_DELIVERY"/> <xs:enumeration value="INTERNATIONAL_DISTRIBUTION_FREIGHT"/> @@ -465,10 +955,19 @@ <xs:enumeration value="INTERNATIONAL_PRIORITY_DISTRIBUTION"/> <xs:enumeration value="INTERNATIONAL_PRIORITY_FREIGHT"/> <xs:enumeration value="PRIORITY_OVERNIGHT"/> + <xs:enumeration value="SAME_DAY"/> + <xs:enumeration value="SAME_DAY_CITY"/> <xs:enumeration value="SMART_POST"/> <xs:enumeration value="STANDARD_OVERNIGHT"/> + <xs:enumeration value="TRANSBORDER_DISTRIBUTION_CONSOLIDATION"/> </xs:restriction> </xs:simpleType> + <xs:complexType name="SignatureImageDetail"> + <xs:sequence> + <xs:element name="Image" type="xs:base64Binary" minOccurs="0"/> + <xs:element name="Notifications" type="ns:Notification" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> <xs:complexType name="SignatureProofOfDeliveryFaxReply"> <xs:annotation> <xs:documentation>FedEx Signature Proof Of Delivery Fax reply.</xs:documentation> @@ -554,6 +1053,7 @@ </xs:annotation> <xs:restriction base="xs:string"> <xs:enumeration value="PDF"/> + <xs:enumeration value="PNG"/> </xs:restriction> </xs:simpleType> <xs:complexType name="SignatureProofOfDeliveryLetterReply"> @@ -635,6 +1135,32 @@ </xs:element> </xs:sequence> </xs:complexType> + <xs:complexType name="SpecialInstructionStatusDetail"> + <xs:sequence> + <xs:element name="Status" type="ns:SpecialInstructionsStatusCode" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the status of the track special instructions requested.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="StatusCreateTime" type="xs:dateTime" minOccurs="0"> + <xs:annotation> + <xs:documentation>Time when the status was changed.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="SpecialInstructionsStatusCode"> + <xs:restriction base="xs:string"> + <xs:enumeration value="ACCEPTED"/> + <xs:enumeration value="CANCELLED"/> + <xs:enumeration value="DENIED"/> + <xs:enumeration value="HELD"/> + <xs:enumeration value="MODIFIED"/> + <xs:enumeration value="RELINQUISHED"/> + <xs:enumeration value="REQUESTED"/> + <xs:enumeration value="SET"/> + </xs:restriction> + </xs:simpleType> <xs:complexType name="StringBarcode"> <xs:annotation> <xs:documentation>Each instance of this data type represents a barcode whose content must be represented as ASCII text (i.e. not binary data).</xs:documentation> @@ -662,22 +1188,64 @@ <xs:enumeration value="USPS"/> </xs:restriction> </xs:simpleType> + <xs:complexType name="TrackAdvanceNotificationDetail"> + <xs:sequence> + <xs:element name="EstimatedTimeOfArrival" type="xs:dateTime" minOccurs="0"/> + <xs:element name="Reason" type="xs:string" minOccurs="0"/> + <xs:element name="Status" type="ns:TrackAdvanceNotificationStatusType" minOccurs="0"/> + <xs:element name="StatusDescription" type="xs:string" minOccurs="0"/> + <xs:element name="StatusTime" type="xs:dateTime" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="TrackAdvanceNotificationStatusType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="BACK_ON_TRACK"/> + <xs:enumeration value="FAIL"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="TrackChargeDetail"> + <xs:sequence> + <xs:element name="Type" type="ns:TrackChargeDetailType" minOccurs="0"/> + <xs:element name="ChargeAmount" type="ns:Money" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="TrackChargeDetailType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="ORIGINAL_CHARGES"/> + </xs:restriction> + </xs:simpleType> <xs:simpleType name="TrackDeliveryLocationType"> <xs:annotation> <xs:documentation>The delivery location at the delivered to address.</xs:documentation> </xs:annotation> <xs:restriction base="xs:string"> + <xs:enumeration value="APARTMENT_OFFICE"/> <xs:enumeration value="FEDEX_LOCATION"/> + <xs:enumeration value="GATE_HOUSE"/> <xs:enumeration value="GUARD_OR_SECURITY_STATION"/> <xs:enumeration value="IN_BOND_OR_CAGE"/> + <xs:enumeration value="LEASING_OFFICE"/> <xs:enumeration value="MAILROOM"/> + <xs:enumeration value="MAIN_OFFICE"/> + <xs:enumeration value="MANAGER_OFFICE"/> <xs:enumeration value="OTHER"/> <xs:enumeration value="PHARMACY"/> <xs:enumeration value="RECEPTIONIST_OR_FRONT_DESK"/> + <xs:enumeration value="RENTAL_OFFICE"/> <xs:enumeration value="RESIDENCE"/> <xs:enumeration value="SHIPPING_RECEIVING"/> </xs:restriction> </xs:simpleType> + <xs:simpleType name="TrackDeliveryOptionType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="APPOINTMENT"/> + <xs:enumeration value="DATE_CERTAIN"/> + <xs:enumeration value="ELECTRONIC_SIGNATURE_RELEASE"/> + <xs:enumeration value="EVENING"/> + <xs:enumeration value="REDIRECT_TO_HOLD_AT_LOCATION"/> + <xs:enumeration value="REROUTE"/> + </xs:restriction> + </xs:simpleType> <xs:complexType name="TrackDetail"> <xs:annotation> <xs:documentation>Detailed tracking information about a particular package.</xs:documentation> @@ -699,16 +1267,12 @@ <xs:documentation>When duplicate tracking numbers exist this data is returned with summary information for each of the duplicates. The summary information is used to determine which of the duplicates the intended tracking number is. This identifier is used on a subsequent track request to retrieve the tracking data for the desired tracking number.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="StatusCode" type="xs:string" minOccurs="0"> + <xs:element name="StatusDetail" type="ns:TrackStatusDetail" minOccurs="0"> <xs:annotation> - <xs:documentation>A code that identifies this type of status. This is the most recent status.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="StatusDescription" type="xs:string" minOccurs="0"> - <xs:annotation> - <xs:documentation>A human-readable description of this status.</xs:documentation> + <xs:documentation>Specifies details about the status of the shipment being tracked.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="CustomerExceptionRequests" type="ns:CustomerExceptionRequestDetail" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="Reconciliation" type="ns:TrackReconciliation" minOccurs="0"> <xs:annotation> <xs:documentation>Used to report the status of a piece of a multiple piece shipment which is no longer traveling with the rest of the packages in the shipment or has not been accounted for.</xs:documentation> @@ -719,6 +1283,8 @@ <xs:documentation>Used to convey information such as. 1. FedEx has received information about a package but has not yet taken possession of it. 2. FedEx has handed the package off to a third party for final delivery. 3. The package delivery has been cancelled</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="DestinationServiceArea" type="xs:string" minOccurs="0"/> + <xs:element name="DestinationServiceAreaDescription" type="xs:string" minOccurs="0"/> <xs:element name="CarrierCode" type="ns:CarrierCodeType" minOccurs="0"> <xs:annotation> <xs:documentation>Identifies a FedEx operating company (transportation).</xs:documentation> @@ -729,24 +1295,34 @@ <xs:documentation>Identifies operating transportation company that is the specific to the carrier code.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="OperatingCompanyOrCarrierDescription" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies a detailed description about the carrier or the operating company.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="CartageAgentCompanyName" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>If the package was interlined to a cartage agent, this is the name of the cartage agent. (Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="ProductionLocationContactAndAddress" type="ns:ContactAndAddress" minOccurs="0"> <xs:annotation> <xs:documentation>Specifies the FXO production centre contact and address.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="OtherIdentifiers" type="ns:TrackPackageIdentifier" minOccurs="0" maxOccurs="unbounded"> + <xs:element name="OtherIdentifiers" type="ns:TrackOtherIdentifierDetail" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>Other related identifiers for this package such as reference numbers.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="ServiceInfo" type="xs:string" minOccurs="0"> + <xs:element name="FormId" type="xs:string" minOccurs="0"> <xs:annotation> - <xs:documentation>Retained for legacy compatibility only. User/screen friendly description of the Service type (e.g. Priority Overnight).</xs:documentation> + <xs:documentation>(Returned for CSR SL only.)</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="ServiceType" type="ns:ServiceType" minOccurs="0"> + <xs:element name="Service" type="ns:TrackServiceDescriptionDetail" minOccurs="0"> <xs:annotation> - <xs:documentation>Strict representation of the Service type (e.g. PRIORITY_OVERNIGHT).</xs:documentation> + <xs:documentation>Specifies details about service such as service description and type.</xs:documentation> </xs:annotation> </xs:element> <xs:element name="PackageWeight" type="ns:Weight" minOccurs="0"> @@ -789,8 +1365,40 @@ <xs:documentation>The number of packages in this shipment.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="TrackReturnLabelType" type="ns:TrackReturnLabelType" minOccurs="0"/> - <xs:element name="TrackReturnDescription" type="xs:string" minOccurs="0"/> + <xs:element name="Charges" type="ns:TrackChargeDetail" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Specifies the details about the SPOC details.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="NickName" type="xs:string" minOccurs="0"/> + <xs:element name="Notes" type="xs:string" minOccurs="0"/> + <xs:element name="Attributes" type="ns:TrackDetailAttributeType" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="ShipmentContents" type="ns:ContentRecord" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="PackageContents" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="ClearanceLocationCode" type="xs:string" minOccurs="0"/> + <xs:element name="Commodities" type="ns:Commodity" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="ReturnDetail" type="ns:TrackReturnDetail" minOccurs="0"/> + <xs:element name="CustomsOptionDetails" type="ns:CustomsOptionDetail" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Specifies the reason for return.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AdvanceNotificationDetail" type="ns:TrackAdvanceNotificationDetail" minOccurs="0"/> + <xs:element name="SpecialHandlings" type="ns:TrackSpecialHandling" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>List of special handlings that applied to this package. (Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Shipper" type="ns:Contact" minOccurs="0"> + <xs:annotation> + <xs:documentation>(Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="PossessionStatus" type="ns:TrackPossessionStatusType" minOccurs="0"> + <xs:annotation> + <xs:documentation>Indicates last-known possession of package (Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="ShipperAddress" type="ns:Address" minOccurs="0"> <xs:annotation> <xs:documentation>The address information for the shipper.</xs:documentation> @@ -801,6 +1409,11 @@ <xs:documentation>The address of the FedEx pickup location/facility.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="OriginStationId" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>(Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="EstimatedPickupTimestamp" type="xs:dateTime" minOccurs="0"> <xs:annotation> <xs:documentation>Estimated package pickup time for shipments that haven't been picked up.</xs:documentation> @@ -821,16 +1434,54 @@ <xs:documentation>Total distance package still has to travel. Returned for Custom Critical shipments.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="SpecialInstructions" type="ns:TrackSpecialInstruction" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Provides additional details about package delivery.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="Recipient" type="ns:Contact" minOccurs="0"> + <xs:annotation> + <xs:documentation>(Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="LastUpdatedDestinationAddress" type="ns:Address" minOccurs="0"> + <xs:annotation> + <xs:documentation>This is the latest updated destination address.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="DestinationAddress" type="ns:Address" minOccurs="0"> <xs:annotation> <xs:documentation>The address this package is to be (or has been) delivered.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="HoldAtLocationContact" type="ns:Contact" minOccurs="0"/> + <xs:element name="HoldAtLocationAddress" type="ns:Address" minOccurs="0"> + <xs:annotation> + <xs:documentation>The address this package is requested to placed on hold.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="DestinationStationId" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>(Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="DestinationLocationAddress" type="ns:Address" minOccurs="0"> <xs:annotation> <xs:documentation>The address of the FedEx delivery location/facility.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="DestinationLocationType" type="ns:FedExLocationType" minOccurs="0"/> + <xs:element name="DestinationLocationTimeZoneOffset" type="xs:string" minOccurs="0"/> + <xs:element name="CommitmentTimestamp" type="xs:dateTime" minOccurs="0"> + <xs:annotation> + <xs:documentation>Date and time the package should be (or should have been) delivered. (Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AppointmentDeliveryTimestamp" type="xs:dateTime" minOccurs="0"> + <xs:annotation> + <xs:documentation>Date and time the package would be delivered if the package has appointment delivery as a special service.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="EstimatedDeliveryTimestamp" type="xs:dateTime" minOccurs="0"> <xs:annotation> <xs:documentation>Projected package delivery time based on ship time stamp, service and destination. Not populated if delivery has already occurred.</xs:documentation> @@ -861,16 +1512,28 @@ <xs:documentation>User/screen friendly representation of the DeliveryLocationType (delivery location at the delivered to address). Can be returned in localized text.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="DeliveryAttempts" type="xs:nonNegativeInteger" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the number of delivery attempts made to deliver the shipment.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="DeliverySignatureName" type="xs:string" minOccurs="0"> <xs:annotation> <xs:documentation>This is either the name of the person that signed for the package or "Signature not requested" or "Signature on file".</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="SignatureProofOfDeliveryAvailable" type="xs:boolean" minOccurs="0"> + <xs:element name="PieceCountVerificationDetails" type="ns:PieceCountVerificationDetail" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> - <xs:documentation>True if signed for by signature image is available.</xs:documentation> + <xs:documentation>Specifies the details about the count of the packages delivered at the delivery location and the count of the packages at the origin.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="TotalUniqueAddressCountInConsolidation" type="xs:nonNegativeInteger" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the total number of unique addresses on the CRNs in a consolidation.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="AvailableImages" type="ns:AvailableImageType" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="Signature" type="ns:SignatureImageDetail" minOccurs="0"/> <xs:element name="NotificationEventsAvailable" type="ns:EMailNotificationEventType" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> <xs:documentation>The types of email notifications that are available for the package.</xs:documentation> @@ -881,9 +1544,9 @@ <xs:documentation>Returned for cargo shipments only when they are currently split across vehicles.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="RedirectToHoldEligibility" type="ns:RedirectToHoldEligibilityType" minOccurs="0"> + <xs:element name="DeliveryOptionEligibilityDetails" type="ns:DeliveryOptionEligibilityDetail" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> - <xs:documentation>Indicates redirection eligibility as determined by tracking service, subject to refinement/override by redirect-to-hold service.</xs:documentation> + <xs:documentation>Specifies the details about the eligibility for different delivery options.</xs:documentation> </xs:annotation> </xs:element> <xs:element name="Events" type="ns:TrackEvent" minOccurs="0" maxOccurs="unbounded"> @@ -893,6 +1556,11 @@ </xs:element> </xs:sequence> </xs:complexType> + <xs:simpleType name="TrackDetailAttributeType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="INCLUDED_IN_WATCHLIST"/> + </xs:restriction> + </xs:simpleType> <xs:complexType name="TrackEvent"> <xs:annotation> <xs:documentation>FedEx scanning information about a package.</xs:documentation> @@ -928,6 +1596,11 @@ <xs:documentation>Address information of the station that is responsible for the scan.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="StationId" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>FedEx location ID where the scan took place. (Returned for CSR SL only.)</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="ArrivalLocation" type="ns:ArrivalLocationType" minOccurs="0"> <xs:annotation> <xs:documentation>Indicates where the arrival actually occurred.</xs:documentation> @@ -945,6 +1618,7 @@ <xs:enumeration value="CUSTOMER_AUTHORIZATION_NUMBER"/> <xs:enumeration value="CUSTOMER_REFERENCE"/> <xs:enumeration value="DEPARTMENT"/> + <xs:enumeration value="DOCUMENT_AIRWAY_BILL"/> <xs:enumeration value="FREE_FORM_REFERENCE"/> <xs:enumeration value="GROUND_INTERNATIONAL"/> <xs:enumeration value="GROUND_SHIPMENT_ID"/> @@ -953,9 +1627,11 @@ <xs:enumeration value="JOB_GLOBAL_TRACKING_NUMBER"/> <xs:enumeration value="ORDER_GLOBAL_TRACKING_NUMBER"/> <xs:enumeration value="ORDER_TO_PAY_NUMBER"/> + <xs:enumeration value="OUTBOUND_LINK_TO_RETURN"/> <xs:enumeration value="PARTNER_CARRIER_NUMBER"/> <xs:enumeration value="PART_NUMBER"/> <xs:enumeration value="PURCHASE_ORDER"/> + <xs:enumeration value="REROUTE_TRACKING_NUMBER"/> <xs:enumeration value="RETURNED_TO_SHIPPER_TRACKING_NUMBER"/> <xs:enumeration value="RETURN_MATERIALS_AUTHORIZATION"/> <xs:enumeration value="SHIPPER_REFERENCE"/> @@ -1010,123 +1686,11 @@ </xs:element> </xs:sequence> </xs:complexType> - <xs:complexType name="TrackNotificationReply"> - <xs:annotation> - <xs:documentation>FedEx Track Notification reply.</xs:documentation> - </xs:annotation> - <xs:sequence> - <xs:element name="HighestSeverity" type="ns:NotificationSeverityType" minOccurs="1"> - <xs:annotation> - <xs:documentation>This contains the severity type of the most severe Notification in the Notifications array.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Notifications" type="ns:Notification" minOccurs="1" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Information about the request/reply such was the transaction successful or not, and any additional information relevant to the request and/or reply. There may be multiple Notifications in a reply.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="TransactionDetail" type="ns:TransactionDetail" minOccurs="0"> - <xs:annotation> - <xs:documentation>Contains the CustomerTransactionDetail that is echoed back to the caller for matching requests and replies and a Localization element for defining the language/translation used in the reply data.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Version" type="ns:VersionId" minOccurs="1"> - <xs:annotation> - <xs:documentation>Contains the version of the reply being used.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="DuplicateWaybill" type="xs:boolean" minOccurs="0"> - <xs:annotation> - <xs:documentation>True if duplicate packages (more than one package with the same tracking number) have been found, the packages array contains information about each duplicate. Use this information to determine which of the tracking numbers is the one you need and resend your request using the tracking number and TrackingNumberUniqueIdentifier for that package.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="MoreDataAvailable" type="xs:boolean" minOccurs="0"> - <xs:annotation> - <xs:documentation>True if additional packages remain to be retrieved.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="PagingToken" type="xs:string" minOccurs="0"> - <xs:annotation> - <xs:documentation>Value that must be passed in a TrackNotification request to retrieve the next set of packages (when MoreDataAvailable = true).</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Packages" type="ns:TrackNotificationPackage" minOccurs="0" maxOccurs="unbounded"> - <xs:annotation> - <xs:documentation>Information about the notifications that are available for this tracking number. If there are duplicates the ship date and destination address information is returned for determining which TrackingNumberUniqueIdentifier to use on a subsequent request.</xs:documentation> - </xs:annotation> - </xs:element> - </xs:sequence> - </xs:complexType> - <xs:complexType name="TrackNotificationRequest"> - <xs:annotation> - <xs:documentation>FedEx Track Notification request.</xs:documentation> - </xs:annotation> + <xs:complexType name="TrackOtherIdentifierDetail"> <xs:sequence> - <xs:element name="WebAuthenticationDetail" type="ns:WebAuthenticationDetail" minOccurs="1"> - <xs:annotation> - <xs:documentation>Descriptive data to be used in authentication of the sender's identity (and right to use FedEx web services).</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="ClientDetail" type="ns:ClientDetail" minOccurs="1"> - <xs:annotation> - <xs:documentation>Descriptive data identifying the client submitting the transaction.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="TransactionDetail" type="ns:TransactionDetail" minOccurs="0"> - <xs:annotation> - <xs:documentation>Contains a free form field that is echoed back in the reply to match requests with replies and data that governs the data payload language/translations</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="Version" type="ns:VersionId" minOccurs="1"> - <xs:annotation> - <xs:documentation>Identifies the version/level of a service operation expected by a caller (in each request) and performed by the callee (in each reply).</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="TrackingNumber" type="xs:string" minOccurs="1"> - <xs:annotation> - <xs:documentation>The tracking number to which the notifications will be triggered from.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="MultiPiece" type="xs:boolean" minOccurs="0"> - <xs:annotation> - <xs:documentation>Indicates whether to return tracking information for all associated packages.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="PagingToken" type="xs:string" minOccurs="0"> - <xs:annotation> - <xs:documentation>When the MoreDataAvailable field is true in a TrackNotificationReply the PagingToken must be sent in the subsequent TrackNotificationRequest to retrieve the next page of data.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="TrackingNumberUniqueId" type="xs:string" minOccurs="0"> - <xs:annotation> - <xs:documentation>Use this field when your original request informs you that there are duplicates of this tracking number. If you get duplicates you will also receive some information about each of the duplicate tracking numbers to enable you to chose one and resend that number along with the TrackingNumberUniqueId to get notifications for that tracking number.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="ShipDateRangeBegin" type="xs:date" minOccurs="0"> - <xs:annotation> - <xs:documentation>To narrow the search to a period in time the ShipDateRangeBegin and ShipDateRangeEnd can be used to help eliminate duplicates.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="ShipDateRangeEnd" type="xs:date" minOccurs="0"> - <xs:annotation> - <xs:documentation>To narrow the search to a period in time the ShipDateRangeBegin and ShipDateRangeEnd can be used to help eliminate duplicates.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="SenderEMailAddress" type="xs:string" minOccurs="1"> - <xs:annotation> - <xs:documentation>Included in the email notification identifying the requester of this notification.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="SenderContactName" type="xs:string" minOccurs="1"> - <xs:annotation> - <xs:documentation>Included in the email notification identifying the requester of this notification.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="NotificationDetail" type="ns:EMailNotificationDetail" minOccurs="1"> - <xs:annotation> - <xs:documentation>Who to send the email notifications to and for which events. The notificationRecipientType and NotifyOnShipment fields are not used in this request.</xs:documentation> - </xs:annotation> - </xs:element> + <xs:element name="PackageIdentifier" type="ns:TrackPackageIdentifier" minOccurs="0"/> + <xs:element name="TrackingNumberUniqueIdentifier" type="xs:string" minOccurs="0"/> + <xs:element name="CarrierCode" type="ns:CarrierCodeType" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="TrackPackageIdentifier"> @@ -1134,18 +1698,41 @@ <xs:documentation>The type and value of the package identifier that is to be used to retrieve the tracking information for a package.</xs:documentation> </xs:annotation> <xs:sequence> - <xs:element name="Value" type="xs:string" minOccurs="1"> + <xs:element name="Type" type="ns:TrackIdentifierType" minOccurs="1"> <xs:annotation> - <xs:documentation>The value to be used to retrieve tracking information for a package.</xs:documentation> + <xs:documentation>The type of the Value to be used to retrieve tracking information for a package (e.g. SHIPPER_REFERENCE, PURCHASE_ORDER, TRACKING_NUMBER_OR_DOORTAG, etc..) .</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="Type" type="ns:TrackIdentifierType" minOccurs="1"> + <xs:element name="Value" type="xs:string" minOccurs="1"> <xs:annotation> - <xs:documentation>The type of the Value to be used to retrieve tracking information for a package (e.g. SHIPPER_REFERENCE, PURCHASE_ORDER, TRACKING_NUMBER_OR_DOORTAG, etc..) .</xs:documentation> + <xs:documentation>The value to be used to retrieve tracking information for a package.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> + <xs:simpleType name="TrackPaymentType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="CASH_OR_CHECK_AT_DESTINATION"/> + <xs:enumeration value="CASH_OR_CHECK_AT_ORIGIN"/> + <xs:enumeration value="CREDIT_CARD_AT_DESTINATION"/> + <xs:enumeration value="CREDIT_CARD_AT_ORIGIN"/> + <xs:enumeration value="OTHER"/> + <xs:enumeration value="RECIPIENT_ACCOUNT"/> + <xs:enumeration value="SHIPPER_ACCOUNT"/> + <xs:enumeration value="THIRD_PARTY_ACCOUNT"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="TrackPossessionStatusType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="BROKER"/> + <xs:enumeration value="CARRIER"/> + <xs:enumeration value="CUSTOMS"/> + <xs:enumeration value="RECIPIENT"/> + <xs:enumeration value="SHIPPER"/> + <xs:enumeration value="SPLIT_STATUS"/> + <xs:enumeration value="TRANSFER_PARTNER"/> + </xs:restriction> + </xs:simpleType> <xs:complexType name="TrackReconciliation"> <xs:annotation> <xs:documentation>Used to report the status of a piece of a multiple piece shipment which is no longer traveling with the rest of the packages in the shipment or has not been accounted for.</xs:documentation> @@ -1188,24 +1775,9 @@ <xs:documentation>Contains the version of the reply being used.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="DuplicateWaybill" type="xs:boolean" minOccurs="0"> - <xs:annotation> - <xs:documentation>True if duplicate packages (more than one package with the same tracking number) have been found, and only limited data will be provided for each one.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="MoreData" type="xs:boolean" minOccurs="0"> - <xs:annotation> - <xs:documentation>True if additional packages remain to be retrieved.</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="PagingToken" type="xs:string" minOccurs="0"> - <xs:annotation> - <xs:documentation>Value that must be passed in a TrackNotification request to retrieve the next set of packages (when MoreDataAvailable = true).</xs:documentation> - </xs:annotation> - </xs:element> - <xs:element name="TrackDetails" type="ns:TrackDetail" minOccurs="0" maxOccurs="unbounded"> + <xs:element name="CompletedTrackDetails" type="ns:CompletedTrackDetail" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> - <xs:documentation>Contains detailed tracking information for the requested packages(s).</xs:documentation> + <xs:documentation>Contains detailed tracking entity information.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> @@ -1235,6 +1807,46 @@ <xs:documentation>The version of the request being used.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="SelectionDetails" type="ns:TrackSelectionDetail" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation>Specifies the details needed to select the shipment being requested to be tracked.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="TransactionTimeOutValueInMilliseconds" type="xs:nonNegativeInteger" minOccurs="0"> + <xs:annotation> + <xs:documentation>The customer can specify a desired time out value for this particular transaction.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="ProcessingOptions" type="ns:TrackRequestProcessingOptionType" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="TrackRequestProcessingOptionType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="INCLUDE_DETAILED_SCANS"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="TrackReturnDetail"> + <xs:sequence> + <xs:element name="MovementStatus" type="ns:TrackReturnMovementStatusType" minOccurs="0"/> + <xs:element name="LabelType" type="ns:TrackReturnLabelType" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + <xs:element name="AuthorizationName" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="TrackReturnLabelType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="EMAIL"/> + <xs:enumeration value="PRINT"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name="TrackReturnMovementStatusType"> + <xs:restriction base="xs:string"> + <xs:enumeration value="MOVEMENT_OCCURRED"/> + <xs:enumeration value="NO_MOVEMENT"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="TrackSelectionDetail"> + <xs:sequence> <xs:element name="CarrierCode" type="ns:CarrierCodeType" minOccurs="0"> <xs:annotation> <xs:documentation>The FedEx operating company (transportation) used for this package's delivery.</xs:documentation> @@ -1245,7 +1857,7 @@ <xs:documentation>Identifies operating transportation company that is the specific to the carrier code.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="PackageIdentifier" type="ns:TrackPackageIdentifier" minOccurs="1"> + <xs:element name="PackageIdentifier" type="ns:TrackPackageIdentifier" minOccurs="0"> <xs:annotation> <xs:documentation>The type and value of the package identifier that is to be used to retrieve the tracking information for a package or group of packages.</xs:documentation> </xs:annotation> @@ -1270,29 +1882,181 @@ <xs:documentation>For tracking by references information either the account number or destination postal code and country must be provided.</xs:documentation> </xs:annotation> </xs:element> + <xs:element name="SecureSpodAccount" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the SPOD account number for the shipment being tracked.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="Destination" type="ns:Address" minOccurs="0"> <xs:annotation> <xs:documentation>For tracking by references information either the account number or destination postal code and country must be provided.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="IncludeDetailedScans" type="xs:boolean" minOccurs="0"> + <xs:element name="PagingDetail" type="ns:PagingDetail" minOccurs="0"> <xs:annotation> - <xs:documentation>If false the reply will contain summary/profile data including current status. If true the reply contains profile + detailed scan activity for each package.</xs:documentation> + <xs:documentation>Specifies the details about how to retrieve the subsequent pages when there is more than one page in the TrackReply.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="PagingToken" type="xs:string" minOccurs="0"> + <xs:element name="CustomerSpecifiedTimeOutValueInMilliseconds" type="xs:nonNegativeInteger" minOccurs="0"> <xs:annotation> - <xs:documentation>When the MoreData field = true in a TrackReply the PagingToken must be sent in the subsequent TrackRequest to retrieve the next page of data.</xs:documentation> + <xs:documentation>The customer can specify a desired time out value for this particular tracking number.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> - <xs:simpleType name="TrackReturnLabelType"> + <xs:complexType name="TrackServiceDescriptionDetail"> + <xs:sequence> + <xs:element name="Type" type="ns:ServiceType" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + <xs:element name="ShortDescription" type="xs:string" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies a shorter description for the service that is calculated per the service code.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> + <xs:complexType name="TrackSpecialHandling"> + <xs:sequence> + <xs:element name="Type" type="ns:TrackSpecialHandlingType" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + <xs:element name="PaymentType" type="ns:TrackPaymentType" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:simpleType name="TrackSpecialHandlingType"> <xs:restriction base="xs:string"> - <xs:enumeration value="EMAIL"/> - <xs:enumeration value="PRINT"/> + <xs:enumeration value="ACCESSIBLE_DANGEROUS_GOODS"/> + <xs:enumeration value="ADULT_SIGNATURE_OPTION"/> + <xs:enumeration value="AIRBILL_AUTOMATION"/> + <xs:enumeration value="AIRBILL_DELIVERY"/> + <xs:enumeration value="ALCOHOL"/> + <xs:enumeration value="AM_DELIVERY_GUARANTEE"/> + <xs:enumeration value="APPOINTMENT_DELIVERY"/> + <xs:enumeration value="BILL_RECIPIENT"/> + <xs:enumeration value="BROKER_SELECT_OPTION"/> + <xs:enumeration value="CALL_BEFORE_DELIVERY"/> + <xs:enumeration value="CALL_TAG"/> + <xs:enumeration value="CALL_TAG_DAMAGE"/> + <xs:enumeration value="CHARGEABLE_CODE"/> + <xs:enumeration value="COD"/> + <xs:enumeration value="COLLECT"/> + <xs:enumeration value="CONSOLIDATION"/> + <xs:enumeration value="CONSOLIDATION_SMALLS_BAG"/> + <xs:enumeration value="CURRENCY"/> + <xs:enumeration value="CUT_FLOWERS"/> + <xs:enumeration value="DATE_CERTAIN_DELIVERY"/> + <xs:enumeration value="DELIVERY_ON_INVOICE_ACCEPTANCE"/> + <xs:enumeration value="DELIVERY_REATTEMPT"/> + <xs:enumeration value="DELIVERY_RECEIPT"/> + <xs:enumeration value="DELIVER_WEEKDAY"/> + <xs:enumeration value="DIRECT_SIGNATURE_OPTION"/> + <xs:enumeration value="DOMESTIC"/> + <xs:enumeration value="DO_NOT_BREAK_DOWN_PALLETS"/> + <xs:enumeration value="DO_NOT_STACK_PALLETS"/> + <xs:enumeration value="DRY_ICE"/> + <xs:enumeration value="DRY_ICE_ADDED"/> + <xs:enumeration value="EAST_COAST_SPECIAL"/> + <xs:enumeration value="ELECTRONIC_COD"/> + <xs:enumeration value="ELECTRONIC_SIGNATURE_SERVICE"/> + <xs:enumeration value="EVENING_DELIVERY"/> + <xs:enumeration value="EXCLUSIVE_USE"/> + <xs:enumeration value="EXTENDED_DELIVERY"/> + <xs:enumeration value="EXTENDED_PICKUP"/> + <xs:enumeration value="EXTRA_LABOR"/> + <xs:enumeration value="EXTREME_LENGTH"/> + <xs:enumeration value="FOOD"/> + <xs:enumeration value="FREIGHT_ON_VALUE_CARRIER_RISK"/> + <xs:enumeration value="FREIGHT_ON_VALUE_OWN_RISK"/> + <xs:enumeration value="FREIGHT_TO_COLLECT"/> + <xs:enumeration value="FULLY_REGULATED_DANGEROUS_GOODS"/> + <xs:enumeration value="GEL_PACKS_ADDED_OR_REPLACED"/> + <xs:enumeration value="GROUND_SUPPORT_FOR_SMARTPOST"/> + <xs:enumeration value="GUARANTEED_FUNDS"/> + <xs:enumeration value="HAZMAT"/> + <xs:enumeration value="HIGH_FLOOR"/> + <xs:enumeration value="HOLD_AT_LOCATION"/> + <xs:enumeration value="HOLIDAY_DELIVERY"/> + <xs:enumeration value="INACCESSIBLE_DANGEROUS_GOODS"/> + <xs:enumeration value="INDIRECT_SIGNATURE_OPTION"/> + <xs:enumeration value="INSIDE_DELIVERY"/> + <xs:enumeration value="INSIDE_PICKUP"/> + <xs:enumeration value="INTERNATIONAL"/> + <xs:enumeration value="INTERNATIONAL_CONTROLLED_EXPORT"/> + <xs:enumeration value="INTERNATIONAL_MAIL_SERVICE"/> + <xs:enumeration value="INTERNATIONAL_TRAFFIC_IN_ARMS_REGULATIONS"/> + <xs:enumeration value="LIFTGATE"/> + <xs:enumeration value="LIFTGATE_DELIVERY"/> + <xs:enumeration value="LIFTGATE_PICKUP"/> + <xs:enumeration value="LIMITED_ACCESS_DELIVERY"/> + <xs:enumeration value="LIMITED_ACCESS_PICKUP"/> + <xs:enumeration value="LIMITED_QUANTITIES_DANGEROUS_GOODS"/> + <xs:enumeration value="MARKING_OR_TAGGING"/> + <xs:enumeration value="NET_RETURN"/> + <xs:enumeration value="NON_BUSINESS_TIME"/> + <xs:enumeration value="NON_STANDARD_CONTAINER"/> + <xs:enumeration value="NO_SIGNATURE_REQUIRED_SIGNATURE_OPTION"/> + <xs:enumeration value="ORDER_NOTIFY"/> + <xs:enumeration value="OTHER"/> + <xs:enumeration value="OTHER_REGULATED_MATERIAL_DOMESTIC"/> + <xs:enumeration value="PACKAGE_RETURN_PROGRAM"/> + <xs:enumeration value="PIECE_COUNT_VERIFICATION"/> + <xs:enumeration value="POISON"/> + <xs:enumeration value="PREPAID"/> + <xs:enumeration value="PRIORITY_ALERT"/> + <xs:enumeration value="PRIORITY_ALERT_PLUS"/> + <xs:enumeration value="PROTECTION_FROM_FREEZING"/> + <xs:enumeration value="RAIL_MODE"/> + <xs:enumeration value="RECONSIGNMENT_CHARGES"/> + <xs:enumeration value="REROUTE_CROSS_COUNTRY_DEFERRED"/> + <xs:enumeration value="REROUTE_CROSS_COUNTRY_EXPEDITED"/> + <xs:enumeration value="REROUTE_LOCAL"/> + <xs:enumeration value="RESIDENTIAL_DELIVERY"/> + <xs:enumeration value="RESIDENTIAL_PICKUP"/> + <xs:enumeration value="RETURNS_CLEARANCE"/> + <xs:enumeration value="RETURNS_CLEARANCE_SPECIAL_ROUTING_REQUIRED"/> + <xs:enumeration value="RETURN_MANAGER"/> + <xs:enumeration value="SATURDAY_DELIVERY"/> + <xs:enumeration value="SHIPMENT_PLACED_IN_COLD_STORAGE"/> + <xs:enumeration value="SINGLE_SHIPMENT"/> + <xs:enumeration value="SMALL_QUANTITY_EXCEPTION"/> + <xs:enumeration value="SORT_AND_SEGREGATE"/> + <xs:enumeration value="SPECIAL_DELIVERY"/> + <xs:enumeration value="SPECIAL_EQUIPMENT"/> + <xs:enumeration value="STANDARD_GROUND_SERVICE"/> + <xs:enumeration value="STORAGE"/> + <xs:enumeration value="SUNDAY_DELIVERY"/> + <xs:enumeration value="THIRD_PARTY_BILLING"/> + <xs:enumeration value="THIRD_PARTY_CONSIGNEE"/> + <xs:enumeration value="TOP_LOAD"/> + <xs:enumeration value="WEEKEND_DELIVERY"/> + <xs:enumeration value="WEEKEND_PICKUP"/> </xs:restriction> </xs:simpleType> + <xs:complexType name="TrackSpecialInstruction"> + <xs:sequence> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + <xs:element name="DeliveryOption" type="ns:TrackDeliveryOptionType" minOccurs="0"/> + <xs:element name="StatusDetail" type="ns:SpecialInstructionStatusDetail" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the status and status update time of the track special instructions.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="OriginalEstimatedDeliveryTimestamp" type="xs:dateTime" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the estimated delivery time that was originally estimated when the shipment was shipped.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="OriginalRequestTime" type="xs:dateTime" minOccurs="0"> + <xs:annotation> + <xs:documentation>Specifies the time the customer requested a change to the shipment.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name="RequestedAppointmentTime" type="ns:AppointmentDetail" minOccurs="0"> + <xs:annotation> + <xs:documentation>The requested appointment time for delivery.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:sequence> + </xs:complexType> <xs:complexType name="TrackSplitShipmentPart"> <xs:annotation> <xs:documentation>Used when a cargo shipment is split across vehicles. This is used to give the status of each part of the shipment.</xs:documentation> @@ -1320,6 +2084,26 @@ </xs:element> </xs:sequence> </xs:complexType> + <xs:complexType name="TrackStatusAncillaryDetail"> + <xs:sequence> + <xs:element name="Reason" type="xs:string" minOccurs="0"/> + <xs:element name="ReasonDescription" type="xs:string" minOccurs="0"/> + <xs:element name="Action" type="xs:string" minOccurs="0"/> + <xs:element name="ActionDescription" type="xs:string" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + <xs:complexType name="TrackStatusDetail"> + <xs:annotation> + <xs:documentation>Specifies the details about the status of the track information for the shipments being tracked.</xs:documentation> + </xs:annotation> + <xs:sequence> + <xs:element name="CreationTime" type="xs:dateTime" minOccurs="0"/> + <xs:element name="Code" type="xs:string" minOccurs="0"/> + <xs:element name="Description" type="xs:string" minOccurs="0"/> + <xs:element name="Location" type="ns:Address" minOccurs="0"/> + <xs:element name="AncillaryDetails" type="ns:TrackStatusAncillaryDetail" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> <xs:complexType name="TransactionDetail"> <xs:annotation> <xs:documentation>Descriptive data that governs data payload language/translations. The TransactionDetail from the request is echoed back to the caller in the corresponding reply.</xs:documentation> @@ -1368,6 +2152,11 @@ <xs:documentation>Used in authentication of the sender's identity.</xs:documentation> </xs:annotation> <xs:sequence> + <xs:element name="ParentCredential" type="ns:WebAuthenticationCredential" minOccurs="0"> + <xs:annotation> + <xs:documentation>This was renamed from cspCredential.</xs:documentation> + </xs:annotation> + </xs:element> <xs:element name="UserCredential" type="ns:WebAuthenticationCredential" minOccurs="1"> <xs:annotation> <xs:documentation>Credential used to authenticate a specific software application. This value is provided by FedEx after registration.</xs:documentation> @@ -1402,7 +2191,7 @@ <xs:documentation>Identifies a system or sub-system which performs an operation.</xs:documentation> </xs:annotation> </xs:element> - <xs:element name="Major" type="xs:int" fixed="5" minOccurs="1"> + <xs:element name="Major" type="xs:int" fixed="10" minOccurs="1"> <xs:annotation> <xs:documentation>Identifies the service business level.</xs:documentation> </xs:annotation> @@ -1421,6 +2210,9 @@ </xs:complexType> </xs:schema> </types> + <message name="SendNotificationsReply"> + <part name="SendNotificationsReply" element="ns:SendNotificationsReply"/> + </message> <message name="SignatureProofOfDeliveryFaxReply"> <part name="SignatureProofOfDeliveryFaxReply" element="ns:SignatureProofOfDeliveryFaxReply"/> </message> @@ -1433,11 +2225,8 @@ <message name="SignatureProofOfDeliveryLetterRequest"> <part name="SignatureProofOfDeliveryLetterRequest" element="ns:SignatureProofOfDeliveryLetterRequest"/> </message> - <message name="TrackNotificationRequest"> - <part name="TrackNotificationRequest" element="ns:TrackNotificationRequest"/> - </message> - <message name="TrackNotificationReply"> - <part name="TrackNotificationReply" element="ns:TrackNotificationReply"/> + <message name="SendNotificationsRequest"> + <part name="SendNotificationsRequest" element="ns:SendNotificationsRequest"/> </message> <message name="TrackReply"> <part name="TrackReply" element="ns:TrackReply"/> @@ -1446,10 +2235,6 @@ <part name="SignatureProofOfDeliveryLetterReply" element="ns:SignatureProofOfDeliveryLetterReply"/> </message> <portType name="TrackPortType"> - <operation name="getTrackNotification" parameterOrder="TrackNotificationRequest"> - <input message="ns:TrackNotificationRequest"/> - <output message="ns:TrackNotificationReply"/> - </operation> <operation name="retrieveSignatureProofOfDeliveryLetter" parameterOrder="SignatureProofOfDeliveryLetterRequest"> <input message="ns:SignatureProofOfDeliveryLetterRequest"/> <output message="ns:SignatureProofOfDeliveryLetterReply"/> @@ -1462,11 +2247,15 @@ <input message="ns:SignatureProofOfDeliveryFaxRequest"/> <output message="ns:SignatureProofOfDeliveryFaxReply"/> </operation> + <operation name="sendNotifications" parameterOrder="SendNotificationsRequest"> + <input message="ns:SendNotificationsRequest"/> + <output message="ns:SendNotificationsReply"/> + </operation> </portType> <binding name="TrackServiceSoapBinding" type="ns:TrackPortType"> <s1:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> - <operation name="getTrackNotification"> - <s1:operation soapAction="getTrackNotification" style="document"/> + <operation name="retrieveSignatureProofOfDeliveryLetter"> + <s1:operation soapAction="http://fedex.com/ws/track/v10/retrieveSignatureProofOfDeliveryLetter" style="document"/> <input> <s1:body use="literal"/> </input> @@ -1474,8 +2263,8 @@ <s1:body use="literal"/> </output> </operation> - <operation name="retrieveSignatureProofOfDeliveryLetter"> - <s1:operation soapAction="retrieveSignatureProofOfDeliveryLetter" style="document"/> + <operation name="track"> + <s1:operation soapAction="http://fedex.com/ws/track/v10/track" style="document"/> <input> <s1:body use="literal"/> </input> @@ -1483,8 +2272,8 @@ <s1:body use="literal"/> </output> </operation> - <operation name="track"> - <s1:operation soapAction="track" style="document"/> + <operation name="sendSignatureProofOfDeliveryFax"> + <s1:operation soapAction="http://fedex.com/ws/track/v10/sendSignatureProofOfDeliveryFax" style="document"/> <input> <s1:body use="literal"/> </input> @@ -1492,8 +2281,8 @@ <s1:body use="literal"/> </output> </operation> - <operation name="sendSignatureProofOfDeliveryFax"> - <s1:operation soapAction="sendSignatureProofOfDeliveryFax" style="document"/> + <operation name="sendNotifications"> + <s1:operation soapAction="http://fedex.com/ws/track/v10/sendNotifications" style="document"/> <input> <s1:body use="literal"/> </input> @@ -1504,7 +2293,7 @@ </binding> <service name="TrackService"> <port name="TrackServicePort" binding="ns:TrackServiceSoapBinding"> - <s1:address location=""/> + <s1:address location="https://wsbeta.fedex.com:443/web-services/track"/> </port> </service> -</definitions> +</definitions> \ No newline at end of file diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml new file mode 100644 index 00000000000..0d84c56599c --- /dev/null +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +/** @var $block \Magento\Framework\View\Element\Template */ + +$track = $block->getData('track'); +$email = $block->getData('storeSupportEmail'); +$fields = [ + 'Status' => 'getStatus', + 'Signed by' => 'getSignedby', + 'Delivered to' => 'getDeliveryLocation', + 'Shipped or billed on' => 'getShippedDate', + 'Service Type' => 'getService', + 'Weight' => 'getWeight', +]; +?> +<table class="data table order tracking" id="tracking-table-popup-<?php /* @noEscape */ echo $track->getTracking(); ?>"> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Order tracking')); ?></caption> + <tbody> + <?php if (is_object($track)): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__('Tracking Number:')); ?></th> + <td class="col value"><?php echo $block->escapeHtml($track->getTracking()); ?></td> + </tr> + <?php if ($track->getCarrierTitle()): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__('Carrier:')); ?></th> + <td class="col value"><?php echo $block->escapeHtml($track->getCarrierTitle()); ?></td> + </tr> + <?php endif; ?> + <?php if ($track->getErrorMessage()): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__('Error:')); ?></th> + <td class="col error"> + <?php echo $block->escapeHtml(__('Tracking information is currently not available. Please ')); ?> + <?php if ($block->getContactUsEnabled()) : ?> + <a href="<?php echo $block->escapeUrl($block->getContactUs()); ?>" target="_blank" + title="<?php echo $block->escapeHtml(__('contact us')); ?>"> + <?php echo $block->escapeHtml(__('contact us')); ?> + </a> + <?php echo $block->escapeHtml(__(' for more information or ')); ?> + <?php endif; ?> + <?php echo $block->escapeHtml(__('email us at ')); ?> + <a href="mailto:<?php /* @noEscape */ echo $email; ?>"><?php /* @noEscape */ echo $email; ?></a> + </td> + </tr> + <?php elseif ($track->getTrackSummary()): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__('Info:')); ?></th> + <td class="col value"><?php echo $block->escapeHtml($track->getTrackSummary()); ?></td> + </tr> + <?php elseif ($track->getUrl()): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__('Track:')); ?></th> + <td class="col value"> + <a href="<?php echo $block->escapeUrl($track->getUrl()); ?>" target="_blank"> + <?php echo $block->escapeUrl($track->getUrl()); ?> + </a> + </td> + </tr> + <?php else: ?> + <?php foreach ($fields as $title => $property): ?> + <?php if (!empty($track->$property())): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__($title . ':')); ?></th> + <td class="col value"><?php echo $block->escapeHtml($track->$property()); ?></td> + </tr> + <?php endif;?> + <?php endforeach; ?> + + <?php if ($track->getDeliverydate()): ?> + <tr> + <th class="col label" scope="row"><?php echo $block->escapeHtml(__('Delivered on:')); ?></th> + <td class="col value"> + <?php /* @noEscape */ echo $block->formatDeliveryDateTime($track->getDeliverydate(), $track->getDeliverytime()); ?> + </td> + </tr> + <?php endif; ?> + <?php endif; ?> + <?php elseif (isset($track['title']) && isset($track['number']) && $track['number']): ?> + <?php /* if the tracking is custom value */ ?> + <tr> + <th class="col label" scope="row"> + <?php echo($track['title'] ? $block->escapeHtml($track['title']) : $block->escapeHtml(__('N/A'))); ?>: + </th> + <td class="col value"><?php echo(isset($track['number']) ? $block->escapeHtml($track['number']) : ''); ?></td> + </tr> + <?php endif; ?> + </tbody> +</table> diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml index e9bb00df8b8..c0f9ab3ab85 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml @@ -4,156 +4,60 @@ * See COPYING.txt for license details. */ +use Magento\Framework\View\Element\Template; + // @codingStandardsIgnoreFile +/** @var $block \Magento\Shipping\Block\Tracking\Popup */ + +$results = $block->getTrackingInfo(); ?> -<?php /** @var $block \Magento\Shipping\Block\Tracking\Popup */ ?> -<?php $_results = $block->getTrackingInfo(); ?> <div class="page tracking"> - <?php if (sizeof($_results)>0): ?> - <?php foreach ($_results as $shipid => $_result): ?> - <?php if ($shipid): ?> - <div class="order subtitle caption"><?php /* @escapeNotVerified */ echo __('Shipment #') . $shipid; ?></div> - <?php endif; ?> - <?php if (sizeof($_result)>0): ?> - <?php $rowCount = sizeof($_result); $counter = 1; ?> - <?php $_id = 0; foreach ($_result as $track): ?> - <div class="table-wrapper"> - <table class="data table order tracking" id="tracking-table-popup-<?php /* @escapeNotVerified */ echo $_id ?>"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Order tracking'); ?></caption> - <tbody> - <?php if (is_object($track)): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Tracking Number:'); ?></th> - <td class="col value"><?php echo $block->escapeHtml($track->getTracking()); ?></td> - </tr> - <?php if ($track->getCarrierTitle()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Carrier:'); ?></th> - <td class="col value"><?php echo $block->escapeHtml($track->getCarrierTitle()); ?></td> - </tr> - <?php endif; ?> - <?php if ($track->getErrorMessage()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Error:'); ?></th> - <td class="col error"><?php /* @escapeNotVerified */ echo __('Tracking information is currently not available. Please '); if ($block->getContactUsEnabled()) : ?><a href="<?php /* @escapeNotVerified */ echo $block->getContactUs() ?>" title="<?php /* @escapeNotVerified */ echo __('contact us') ?>" onclick="this.target='_blank'"><?php /* @escapeNotVerified */ echo __('contact us') ?></a><?php /* @escapeNotVerified */ echo __(' for more information or '); endif; /* @escapeNotVerified */ echo __('email us at '); ?><a href="mailto:<?php /* @escapeNotVerified */ echo $block->getStoreSupportEmail() ?>"><?php /* @escapeNotVerified */ echo $block->getStoreSupportEmail() ?></a></td> - </tr> - <?php elseif ($track->getTrackSummary()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Info:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getTrackSummary(); ?></td> - </tr> - <?php elseif ($track->getUrl()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Track:'); ?></th> - <td class="col value"><a href="<?php echo $block->escapeHtml($track->getUrl()); ?>" onclick="this.target='_blank'"><?php echo $block->escapeHtml($track->getUrl()); ?></a></td> - </tr> - <?php else: ?> - <?php if ($track->getStatus()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Status:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getStatus(); ?></td> - </tr> - <?php endif; ?> - - <?php if ($track->getDeliverydate()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Delivered on:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $block->formatDeliveryDateTime($track->getDeliverydate(), $track->getDeliverytime()); ?></td> - </tr> - <?php endif; ?> - - <?php if ($track->getSignedby()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Signed by:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getSignedby(); ?></td> - </tr> - <?php endif; ?> - - <?php if ($track->getDeliveryLocation()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Delivered to:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getDeliveryLocation(); ?></td> - </tr> - <?php endif; ?> - - <?php if ($track->getShippedDate()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Shipped or billed on:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getShippedDate(); ?></td> - </tr> - <?php endif; ?> - - <?php if ($track->getService()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Service Type:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getService(); ?></td> - </tr> - <?php endif; ?> - - <?php if ($track->getWeight()): ?> - <tr> - <th class="col label" scope="row"><?php /* @escapeNotVerified */ echo __('Weight:'); ?></th> - <td class="col value"><?php /* @escapeNotVerified */ echo $track->getWeight(); ?></td> - </tr> - <?php endif; ?> - <?php endif; ?> - <?php elseif (isset($track['title']) && isset($track['number']) && $track['number']): ?> - <?php /* if the tracking is custom value */ ?> - <tr> - <th class="col label" scope="row"><?php echo($track['title'] ? $block->escapeHtml($track['title']) : __('N/A')); ?>:</th> - <td class="col value"><?php echo(isset($track['number']) ? $block->escapeHtml($track['number']) : ''); ?></td> - </tr> - <?php endif; ?> - </tbody> - </table> - </div> - <?php if (is_object($track) && sizeof($track->getProgressdetail())>0): ?> + <?php if (!empty($results)): ?> + <?php foreach ($results as $shipId => $result): ?> + <?php if ($shipId): ?> + <div class="order subtitle caption"><?php echo $block->escapeHtml(__('Shipment #')) . $shipId; ?></div> + <?php endif; ?> + <?php if (!empty($result)): ?> + <?php foreach ($result as $counter => $track): ?> <div class="table-wrapper"> - <table class="data table order tracking" id="track-history-table-<?php /* @escapeNotVerified */ echo $track->getTracking(); ?>"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Track history'); ?></caption> - <thead> - <tr> - <th class="col location" scope="col"><?php /* @escapeNotVerified */ echo __('Location') ?></th> - <th class="col date" scope="col"><?php /* @escapeNotVerified */ echo __('Date') ?></th> - <th class="col time" scope="col"><?php /* @escapeNotVerified */ echo __('Local Time') ?></th> - <th class="col description" scope="col"><?php /* @escapeNotVerified */ echo __('Description') ?></th> - </tr> - </thead> - <tbody> - <?php foreach ($track->getProgressdetail() as $_detail): ?> - <?php $_detailDate = (isset($_detail['deliverydate']) ? $block->formatDeliveryDate($_detail['deliverydate']) : '') ?> - <?php $_detailTime = (isset($_detail['deliverytime']) ? $block->formatDeliveryTime($_detail['deliverytime'], $_detail['deliverydate']) : '') ?> - <tr> - <td data-th="<?php echo $block->escapeHtml(__('Location')) ?>" class="col location"><?php echo(isset($_detail['deliverylocation']) ? $_detail['deliverylocation'] : ''); ?></td> - <td data-th="<?php echo $block->escapeHtml(__('Date')) ?>" class="col date"><?php /* @escapeNotVerified */ echo $_detailDate ?></td> - <td data-th="<?php echo $block->escapeHtml(__('Local Time')) ?>" class="col time"><?php /* @escapeNotVerified */ echo $_detailTime ?></td> - <td data-th="<?php echo $block->escapeHtml(__('Description')) ?>" class="col description"><?php echo(isset($_detail['activity']) ? $_detail['activity'] : '') ?></td> - </tr> - <?php endforeach; ?> - </tbody> - </table> + <?php + $block->addChild('shipping.tracking.details.' . $counter, Template::class, [ + 'track' => $track, + 'template' => 'Magento_Shipping::tracking/details.phtml', + 'storeSupportEmail' => $block->getStoreSupportEmail() + ] + ); + ?> + <?php echo $block->getChildHtml('shipping.tracking.details.' . $counter); ?> </div> - <?php endif; ?> - <?php if ($counter != $rowCount): ?> - <?php endif; ?> - <?php $counter++; ?> - <?php /* end for each tracking information */ ?> - <?php endforeach; ?> - <?php else: ?> - <div class="message info empty"><div><?php /* @escapeNotVerified */ echo __('There is no tracking available for this shipment.'); ?></div></div> - <?php endif; ?> - - <?php endforeach; ?> + <?php if (!empty($track->getProgressdetail())): ?> + <?php + $block->addChild('shipping.tracking.progress.'. $counter, Template::class, [ + 'track' => $track, + 'template' => 'Magento_Shipping::tracking/progress.phtml' + ]); + ?> + <?php echo $block->getChildHtml('shipping.tracking.progress.' . $counter); ?> + <?php endif; ?> + <?php endforeach; ?> + <?php else: ?> + <div class="message info empty"> + <div><?php echo $block->escapeHtml(__('There is no tracking available for this shipment.')); ?></div> + </div> + <?php endif; ?> + <?php endforeach; ?> <?php else: ?> - <div class="message info empty"><div><?php /* @escapeNotVerified */ echo __('There is no tracking available.'); ?></div></div> + <div class="message info empty"> + <div><?php echo $block->escapeHtml(__('There is no tracking available.')); ?></div> + </div> <?php endif; ?> <div class="actions"> <button type="button" - title="<?php /* @escapeNotVerified */ echo __('Close Window') ?>" + title="<?php echo $block->escapeHtml(__('Close Window')); ?>" class="action close" onclick="window.close(); window.opener.focus();"> - <span><?php /* @escapeNotVerified */ echo __('Close Window') ?></span> + <span><?php echo $block->escapeHtml(__('Close Window')); ?></span> </button> </div> </div> diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/progress.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/progress.phtml new file mode 100644 index 00000000000..d5ce13a277f --- /dev/null +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/progress.phtml @@ -0,0 +1,43 @@ +<?php +/** +* Copyright © 2016 Magento. All rights reserved. +* See COPYING.txt for license details. +*/ + +// @codingStandardsIgnoreFile + +/** @var $block \Magento\Framework\View\Element\Template */ +$track = $block->getData('track'); +?> +<div class="table-wrapper"> + <table class="data table order tracking" id="track-history-table-<?php /* @noEscape */ echo $track->getTracking(); ?>"> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Track history')); ?></caption> + <thead> + <tr> + <th class="col location" scope="col"><?php echo $block->escapeHtml(__('Location')); ?></th> + <th class="col date" scope="col"><?php echo $block->escapeHtml(__('Date')); ?></th> + <th class="col time" scope="col"><?php echo $block->escapeHtml(__('Local Time')); ?></th> + <th class="col description" scope="col"><?php echo $block->escapeHtml(__('Description')); ?></th> + </tr> + </thead> + <tbody> + <?php foreach ($track->getProgressdetail() as $detail): ?> + <?php $detailDate = (!empty($detail['deliverydate']) ? $block->formatDeliveryDate($detail['deliverydate']) : ''); ?> + <?php $detailTime = (!empty($detail['deliverytime']) ? $block->formatDeliveryTime($detail['deliverytime'], $detail['deliverydate']) : ''); ?> + <tr> + <td data-th="<?php echo $block->escapeHtml(__('Location')); ?>" class="col location"> + <?php echo(!empty($detail['deliverylocation']) ? $block->escapeHtml($detail['deliverylocation']) : ''); ?> + </td> + <td data-th="<?php echo $block->escapeHtml(__('Date')); ?>" class="col date"> + <?php /* @noEscape */ echo $detailDate; ?> + </td> + <td data-th="<?php echo $block->escapeHtml(__('Local Time')); ?>" class="col time"> + <?php /* @noEscape */ echo $detailTime; ?></td> + <td data-th="<?php echo $block->escapeHtml(__('Description')); ?>" class="col description"> + <?php echo(!empty($detail['activity']) ? $block->escapeHtml($detail['activity']) : ''); ?> + </td> + </tr> + <?php endforeach; ?> + </tbody> + </table> +</div> \ No newline at end of file -- GitLab From e8c3f113dd84342b212280ffc2a44b98bf3c2683 Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Mon, 8 Aug 2016 11:05:38 +0300 Subject: [PATCH 189/838] MAGETWO-55953: Exception occurs when tracking shipment with invalid FedEx tracking number - Fixed failed static tests --- app/code/Magento/Fedex/Model/Carrier.php | 3 +++ app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php | 4 ++++ .../Shipping/view/frontend/templates/tracking/details.phtml | 2 +- .../Shipping/view/frontend/templates/tracking/popup.phtml | 6 +++--- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php index b3ffabf74da..753388dc17b 100644 --- a/app/code/Magento/Fedex/Model/Carrier.php +++ b/app/code/Magento/Fedex/Model/Carrier.php @@ -1550,8 +1550,11 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C } /** + * Parse track details response from Fedex * @param \stdClass $trackInfo * @return array + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ private function processTrackingDetails(\stdClass $trackInfo) { diff --git a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php index 4a54993508c..612b0b3d6a6 100644 --- a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php @@ -224,6 +224,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase * @param string $rateType * @param float $expected * @dataProvider collectRatesDataProvider + * @SuppressWarnings(PHPMD.CamelCaseVariableName) */ public function testCollectRatesRateAmountOriginBased($amount, $rateType, $expected) { @@ -356,6 +357,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking + * @SuppressWarnings(PHPMD.CamelCaseVariableName) */ public function testGetTrackingErrorResponse() { @@ -389,6 +391,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking + * @SuppressWarnings(PHPMD.CamelCaseVariableName) */ public function testGetTracking() { @@ -455,6 +458,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking + * @SuppressWarnings(PHPMD.CamelCaseVariableName) */ public function testGetTrackingWithEvents() { diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml index 0d84c56599c..d655d96e1dd 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/details.phtml @@ -67,7 +67,7 @@ $fields = [ <?php foreach ($fields as $title => $property): ?> <?php if (!empty($track->$property())): ?> <tr> - <th class="col label" scope="row"><?php echo $block->escapeHtml(__($title . ':')); ?></th> + <th class="col label" scope="row"><?php /* @noEscape */ echo $block->escapeHtml(__($title . ':')); ?></th> <td class="col value"><?php echo $block->escapeHtml($track->$property()); ?></td> </tr> <?php endif;?> diff --git a/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml b/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml index c0f9ab3ab85..412cb4b411a 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/tracking/popup.phtml @@ -16,7 +16,7 @@ $results = $block->getTrackingInfo(); <?php if (!empty($results)): ?> <?php foreach ($results as $shipId => $result): ?> <?php if ($shipId): ?> - <div class="order subtitle caption"><?php echo $block->escapeHtml(__('Shipment #')) . $shipId; ?></div> + <div class="order subtitle caption"><?php /* @noEscape */ echo $block->escapeHtml(__('Shipment #')) . $shipId; ?></div> <?php endif; ?> <?php if (!empty($result)): ?> <?php foreach ($result as $counter => $track): ?> @@ -29,7 +29,7 @@ $results = $block->getTrackingInfo(); ] ); ?> - <?php echo $block->getChildHtml('shipping.tracking.details.' . $counter); ?> + <?php /* @noEscape */ echo $block->getChildHtml('shipping.tracking.details.' . $counter); ?> </div> <?php if (!empty($track->getProgressdetail())): ?> <?php @@ -38,7 +38,7 @@ $results = $block->getTrackingInfo(); 'template' => 'Magento_Shipping::tracking/progress.phtml' ]); ?> - <?php echo $block->getChildHtml('shipping.tracking.progress.' . $counter); ?> + <?php /* @noEscape */echo $block->getChildHtml('shipping.tracking.progress.' . $counter); ?> <?php endif; ?> <?php endforeach; ?> <?php else: ?> -- GitLab From ea1fae35d638826d3b1b4362273624f288016fa8 Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Mon, 8 Aug 2016 11:34:48 +0300 Subject: [PATCH 190/838] MAGETWO-55953: Exception occurs when tracking shipment with invalid FedEx tracking number - Changed controversial rule for suppress warning annotation --- app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php index 612b0b3d6a6..a042e1e2809 100644 --- a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php @@ -224,7 +224,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase * @param string $rateType * @param float $expected * @dataProvider collectRatesDataProvider - * @SuppressWarnings(PHPMD.CamelCaseVariableName) + * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testCollectRatesRateAmountOriginBased($amount, $rateType, $expected) { @@ -357,7 +357,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking - * @SuppressWarnings(PHPMD.CamelCaseVariableName) + * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testGetTrackingErrorResponse() { @@ -391,7 +391,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking - * @SuppressWarnings(PHPMD.CamelCaseVariableName) + * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testGetTracking() { @@ -458,7 +458,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking - * @SuppressWarnings(PHPMD.CamelCaseVariableName) + * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testGetTrackingWithEvents() { -- GitLab From 92c29730de5eb73df8980c1b42cc956a09be7e27 Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Mon, 8 Aug 2016 11:51:59 +0300 Subject: [PATCH 191/838] MAGETWO-55953: Exception occurs when tracking shipment with invalid FedEx tracking number - Added code ignore annotations --- .../Magento/Fedex/Test/Unit/Model/CarrierTest.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php index a042e1e2809..385ddf84148 100644 --- a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php @@ -224,7 +224,6 @@ class CarrierTest extends \PHPUnit_Framework_TestCase * @param string $rateType * @param float $expected * @dataProvider collectRatesDataProvider - * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testCollectRatesRateAmountOriginBased($amount, $rateType, $expected) { @@ -232,6 +231,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase ->method('isSetFlag') ->willReturn(true); + // @codingStandardsIgnoreStart $netAmount = new \stdClass(); $netAmount->Amount = $amount; @@ -249,6 +249,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase $response = new \stdClass(); $response->HighestSeverity = 'SUCCESS'; $response->RateReplyDetails = $rate; + // @codingStandardsIgnoreEnd $this->model->expects(static::any()) ->method('_getCachedQuotes') @@ -357,17 +358,18 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking - * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testGetTrackingErrorResponse() { $tracking = '123456789012'; $errorMessage = 'Tracking information is unavailable.'; + // @codingStandardsIgnoreStart $response = new \stdClass(); $response->HighestSeverity = 'ERROR'; $response->Notifications = new \stdClass(); $response->Notifications->Message = $errorMessage; + // @codingStandardsIgnoreEnd $this->model->expects(static::once()) ->method('_getCachedQuotes') @@ -391,12 +393,12 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking - * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testGetTracking() { $tracking = '123456789012'; + // @codingStandardsIgnoreStart $response = new \stdClass(); $response->HighestSeverity = 'SUCCESS'; $response->CompletedTrackDetails = new \stdClass(); @@ -422,6 +424,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase $trackDetails->PackageWeight->Units = 'LB'; $response->CompletedTrackDetails->TrackDetails = [$trackDetails]; + // @codingStandardsIgnoreEnd $this->model->expects(static::once()) ->method('_getCachedQuotes') @@ -458,12 +461,12 @@ class CarrierTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Fedex\Model\Carrier::getTracking - * @SuppressWarnings(PHPMD.CamelCasePropertyName) */ public function testGetTrackingWithEvents() { $tracking = '123456789012'; + // @codingStandardsIgnoreStart $response = new \stdClass(); $response->HighestSeverity = 'SUCCESS'; $response->CompletedTrackDetails = new \stdClass(); @@ -481,6 +484,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase $trackDetails->Events = $event; $response->CompletedTrackDetails->TrackDetails = $trackDetails; + // @codingStandardsIgnoreEnd $this->model->expects(static::once()) ->method('_getCachedQuotes') -- GitLab From 03952ff994545d7d6ae4f3a2c993857c5b812139 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Mon, 8 Aug 2016 13:03:02 +0300 Subject: [PATCH 192/838] MAGETWO-55267: Modify Update Grid --- setup/view/magento/setup/extension-grid.phtml | 2 +- setup/view/magento/setup/update-extension-grid.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index 1b181c5bc9b..e309f020518 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -24,7 +24,7 @@ <div class="item-number">{{countOfUpdate}}</div> <div class="item-title">Updates<br />Available</div> <button ui-sref="root.update" href="#update-extension-grid" - ng-class="{'disabled' : !countOfUpdate}" + ng-class="{'disabled' : !countOfUpdate, 'goUpdate' : countOfUpdate}" type="button" class="btn"> Review Updates </button> diff --git a/setup/view/magento/setup/update-extension-grid.phtml b/setup/view/magento/setup/update-extension-grid.phtml index c1f1a40f17b..6ee2784079e 100644 --- a/setup/view/magento/setup/update-extension-grid.phtml +++ b/setup/view/magento/setup/update-extension-grid.phtml @@ -13,7 +13,7 @@ </span> </div> </div> -<div class="admin__data-grid-outer-wrap"> +<div class="admin__data-grid-outer-wrap" id="updateExtensionGrid"> <div class="admin__data-grid-header"> <div class="admin__data-grid-header-row row row-gutter"> <div class="col-xs-3"> -- GitLab From 7633c21075ec8f04fad606075e4dfb4741f6ebc1 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Mon, 8 Aug 2016 14:13:08 +0300 Subject: [PATCH 193/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/templates/dynamic-rows/templates/default.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html index 0031bc75651..cf93e5fa23f 100644 --- a/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html +++ b/app/code/Magento/Ui/view/base/web/templates/dynamic-rows/templates/default.html @@ -49,7 +49,7 @@ </tr> </tbody> - <tfoot visible="element.addButton || (!!$data.recordData().length && (pages() > 1))"> + <tfoot visible="element.addButton || (!!element.getRecordCount() && (element.pages() > 1))"> <tr> <td attr="{'colspan': element.getColumnsCount()}" visible="element.addButton || pages() > 1"> @@ -60,7 +60,7 @@ <span text="addButtonLabel"/> </button> - <div class="admin__control-table-pagination" visible="!!element.getRecordCount() && pages() > 1"> + <div class="admin__control-table-pagination" visible="!!element.getRecordCount() && element.pages() > 1"> <div class="admin__data-grid-pager"> <button class="action-previous" type="button" data-bind="attr: {title: $t('Previous Page')}, click: previousPage, disable: isFirst()"></button> <input class="admin__control-text" type="number" data-bind="attr: {id: ++ko.uid}, value: currentPage"> -- GitLab From 0548f22e0e90adef4d7ffd7a8df32a2a50eda962 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Mon, 8 Aug 2016 14:22:00 +0300 Subject: [PATCH 194/838] MAGETWO-53852: Event update works incorrectly --- .../Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 035a115cd12..7d173cec0bf 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -153,7 +153,7 @@ define([ dnd: '${ $.dndConfig.name }' }, pages: 1, - pageSize: 5, + pageSize: 20, relatedData: [], currentPage: 1, recordDataCache: [], @@ -659,8 +659,6 @@ define([ * @param {Number|String} prop - additional property to element */ processingAddChild: function (ctx, index, prop) { - console.log('3', this.name); - this.bubble('addChild', false); if (this.relatedData.length && this.relatedData.length % this.pageSize === 0) { -- GitLab From 0913ee74498bd54db7ac80cd3c13e891c7fdd20e Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 8 Aug 2016 15:01:19 +0300 Subject: [PATCH 195/838] MAGETWO-55271: Cover with Functional Tests --- .../Magento/Setup/Test/Block/Readiness.php | 39 +++++++++++++++++++ .../Test/TestCase/AbstractExtensionTest.php | 24 +++++++++++- .../TestCase/ExtensionMultipleUpdateTest.php | 25 ++++++++++-- .../TestCase/ExtensionMultipleUpdateTest.xml | 5 +++ 4 files changed, 88 insertions(+), 5 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php index 9be5c9479de..4654b4dc4c9 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php @@ -8,6 +8,7 @@ namespace Magento\Setup\Test\Block; use Magento\Mtf\Block\Block; use Magento\Mtf\Client\Locator; +use Magento\Setup\Test\Fixture\Extension; /** * Readiness block. @@ -28,6 +29,20 @@ class Readiness extends Block */ protected $next = "[ng-click*='next']"; + /** + * 'Try Again' button. + * + * @var string + */ + protected $tryAgain = "[ng-click*='forceReload']"; + + /** + * Trash Bin icon. + * + * @var string + */ + protected $removeExtension = '//li[contains(text(), \'%s\')]//button'; + /** * 'Completed!' message. * [ng-switch-when="true"] @@ -98,6 +113,30 @@ class Readiness extends Block $this->_rootElement->find($this->next, Locator::SELECTOR_CSS)->click(); } + /** + * Click on 'Try Again' button. + * + * @return void + */ + public function clickTryAgain() + { + $this->_rootElement->find($this->tryAgain, Locator::SELECTOR_CSS)->click(); + $this->waitForElementVisible($this->completedMessage, Locator::SELECTOR_CSS); + } + + /** + * Click Trash Bin icon. + * + * @param Extension $extension + * @return void + */ + public function clickRemoveExtension(Extension $extension) + { + $removeExtension = sprintf($this->removeExtension, $extension->getExtensionName()); + + $this->_rootElement->find($removeExtension, Locator::SELECTOR_XPATH)->click(); + } + /** * Get Updater application check result. * diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php index bcc3b65c8d9..f9358abe828 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/AbstractExtensionTest.php @@ -79,14 +79,34 @@ abstract class AbstractExtensionTest extends Injectable AssertSuccessfulReadinessCheck $assertReadiness, BackupOptions $backupOptions ) { + $this->readinessCheck($assertReadiness); + $this->setupWizard->getReadiness()->clickNext(); + $this->backup($backupOptions); + $this->setupWizard->getCreateBackup()->clickNext(); + } + + /** + * Perform Readiness check. + * + * @param AssertSuccessfulReadinessCheck $assertReadiness + */ + protected function readinessCheck(AssertSuccessfulReadinessCheck $assertReadiness) + { // Readiness Check $this->setupWizard->getReadiness()->clickReadinessCheck(); + $assertReadiness->processAssert($this->setupWizard); - $this->setupWizard->getReadiness()->clickNext(); + } + /** + * Perform Backup. + * + * @param BackupOptions $backupOptions + */ + protected function backup(BackupOptions $backupOptions) + { // Create Backup page $this->setupWizard->getCreateBackup()->fill($backupOptions); - $this->setupWizard->getCreateBackup()->clickNext(); } /** diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index c99fd15a02d..8bc66c1be67 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -34,6 +34,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest * @param AssertSelectSeveralExtensions $assertSelectSeveralExtensions * @param $needAuthentication * @param array $extensions + * @param array $removeExtensions */ public function test( FixtureFactory $fixtureFactory, @@ -46,12 +47,17 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage, AssertSelectSeveralExtensions $assertSelectSeveralExtensions, $needAuthentication, - array $extensions + array $extensions, + array $removeExtensions ) { foreach ($extensions as $key => $options) { $extensions[$key] = $fixtureFactory->create(Extension::class, $options); } + foreach ($removeExtensions as $key => $options) { + $removeExtensions[$key] = $fixtureFactory->create(Extension::class, $options); + } + // Authenticate in admin area $this->adminDashboard->open(); @@ -83,15 +89,28 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest // Click general "Update" button $this->setupWizard->getExtensionsUpdateGrid()->clickUpdateAllButton(); - $this->readinessCheckAndBackup($assertReadiness, $backupOptions); + $this->readinessCheck($assertReadiness); + + /** @var Extension $removeExtension */ + foreach ($removeExtensions as $removeExtension) { + $this->setupWizard->getReadiness()->clickRemoveExtension($removeExtension); + } + + $this->setupWizard->getReadiness()->clickTryAgain(); + $assertReadiness->processAssert($this->setupWizard); + $this->setupWizard->getReadiness()->clickNext(); + $this->backup($backupOptions); + $this->setupWizard->getCreateBackup()->clickNext(); // Start installing $this->setupWizard->getUpdaterExtension()->clickStartButton(); + $updatedExtensions = array_diff_key($extensions, $removeExtensions); + // Check success message $assertMultipleUpdateSuccessMessage->processAssert( $this->setupWizard, - $extensions, + $updatedExtensions, AssertSuccessMessage::TYPE_UPDATE ); diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml index dfe368f06d7..f1d07e3b99c 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml @@ -17,6 +17,11 @@ <item name="dataset" xsi:type="string">secondExtension</item> </item> </data> + <data name="removeExtensions" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="dataset" xsi:type="string">firstExtension</item> + </item> + </data> </variation> </testCase> </config> -- GitLab From cf4ba63dec482610ea78c4b8b2295f78f6f65a5c Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 8 Aug 2016 15:13:27 +0300 Subject: [PATCH 196/838] MAGETWO-55271: Cover with Functional Tests --- .../Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index 8bc66c1be67..ca36c33a949 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -35,6 +35,8 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest * @param $needAuthentication * @param array $extensions * @param array $removeExtensions + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function test( FixtureFactory $fixtureFactory, -- GitLab From 632d8fb8ab92f2de8b00a9e491fe884b6f1536db Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Mon, 8 Aug 2016 16:04:02 +0300 Subject: [PATCH 197/838] MAGETWO-53852: Event update works incorrectly --- .../base/web/js/dynamic-rows/dynamic-rows.js | 44 ++++++++++--------- .../view/base/web/js/dynamic-rows/record.js | 19 +++++++- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 7d173cec0bf..041501b7410 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -160,6 +160,9 @@ define([ startIndex: 0 }, + /** + * Sets record data to cache + */ setRecordDataToCache: function (data) { this.recordDataCache = this.recordDataCache && data.length > this.recordDataCache.length ? data : this.recordDataCache; @@ -177,7 +180,9 @@ define([ 'processingDeleteRecord', 'onChildrenUpdate', 'checkDefaultState', - 'renderColumnsHeader' + 'renderColumnsHeader', + 'deleteHandler', + 'setDefaultState' ); this._super() @@ -247,15 +252,9 @@ define([ initElement: function (elem) { this._super(); elem.on({ - 'deleteRecord': function (index, id) { - this.deleteHandler(index, id); - }.bind(this), - 'update': function (state) { - this.onChildrenUpdate(state); - }.bind(this), - 'addChild': function () { - this.setDefaultState(); - }.bind(this) + 'deleteRecord': this.deleteHandler, + 'update': this.onChildrenUpdate, + 'addChild': this.setDefaultState }); return this; @@ -270,7 +269,8 @@ define([ deleteHandler: function (index, id) { this.setDefaultState(); this.processingDeleteRecord(index, id); - this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.pagesChanged[this.currentPage()] = + !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); this.changed(_.some(this.pagesChanged)); }, @@ -307,19 +307,20 @@ define([ changed.forEach(function (elem) { changedElemDataScope = elem.dataScope.split('.'); changedElemDataScope.splice(0, dataScope.length); - changedElemDataScope[0] = (parseInt(changedElemDataScope[0], 10) - this.pageSize * (this.currentPage() - 1)).toString(); - this.setValueByPath(this.defaultPagesState[this.currentPage()], changedElemDataScope, elem.initialValue); + changedElemDataScope[0] = + (parseInt(changedElemDataScope[0], 10) - this.pageSize * (this.currentPage() - 1)).toString(); + this.setValueByPath( + this.defaultPagesState[this.currentPage()], + changedElemDataScope, elem.initialValue + ); }, this); } - this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.pagesChanged[this.currentPage()] = + !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); this.changed(_.some(this.pagesChanged)); }, - compare: function (a1,a2) { - return compareArrays(a1,a2) - }, - /** * Set default dynamic-rows state * @@ -426,10 +427,12 @@ define([ return initialize; })); - this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.pagesChanged[this.currentPage()] = + !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); this.changed(_.some(this.pagesChanged)); } else if (this.hasInitialPagesState[this.currentPage()]) { - this.pagesChanged[this.currentPage()] = !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); + this.pagesChanged[this.currentPage()] = + !compareArrays(this.defaultPagesState[this.currentPage()], this.arrayFilter(this.getChildItems())); this.changed(_.some(this.pagesChanged)); } }, @@ -438,6 +441,7 @@ define([ * Filters out deleted items from array * * @param {Array} data + * * @returns {Array} filtered array */ arrayFilter: function (data) { diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js index 5c9a51e4342..595031a329b 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/record.js @@ -35,14 +35,31 @@ define([ } }, + /** + * Extends instance with default config, calls initialize of parent + * class, calls initChildren method, set observe variable. + * Use parent "track" method - wrapper observe array + * + * @returns {Object} Chainable. + */ initialize: function () { var self = this; this._super(); - registry.async(this.name + '.' + this.positionProvider)(function(component){ + registry.async(this.name + '.' + this.positionProvider)(function (component) { + + /** + * Overwrite hasChanged method + * + * @returns {Boolean} + */ component.hasChanged = function () { + + /* eslint-disable eqeqeq */ return this.value().toString() != this.initialValue.toString(); + + /* eslint-enable eqeqeq */ }; if (!component.initialValue) { -- GitLab From 88f80fd405d5cc81df668b8828d1943280e2f00b Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Mon, 8 Aug 2016 16:54:04 +0300 Subject: [PATCH 198/838] MAGETWO-56115: [Github] #5857 Impossible to configure custom availability gateway validator - Added check for payment info instance availability --- .../Magento/Payment/Model/Method/Adapter.php | 19 +-- .../Test/Unit/Model/Method/AdapterTest.php | 114 ++++++++++-------- 2 files changed, 73 insertions(+), 60 deletions(-) diff --git a/app/code/Magento/Payment/Model/Method/Adapter.php b/app/code/Magento/Payment/Model/Method/Adapter.php index 1d693e11fe5..07a4dcdef5f 100644 --- a/app/code/Magento/Payment/Model/Method/Adapter.php +++ b/app/code/Magento/Payment/Model/Method/Adapter.php @@ -268,14 +268,17 @@ class Adapter implements MethodInterface $checkResult = new DataObject(); $checkResult->setData('is_available', true); try { - $validator = $this->getValidatorPool()->get('availability'); - $result = $validator->validate( - [ - 'payment' => $this->paymentDataObjectFactory->create($this->getInfoInstance()) - ] - ); - - $checkResult->setData('is_available', $result->isValid()); + $infoInstance = $this->getInfoInstance(); + if ($infoInstance !== null) { + $validator = $this->getValidatorPool()->get('availability'); + $result = $validator->validate( + [ + 'payment' => $this->paymentDataObjectFactory->create($infoInstance) + ] + ); + + $checkResult->setData('is_available', $result->isValid()); + } } catch (\Exception $e) { // pass } diff --git a/app/code/Magento/Payment/Test/Unit/Model/Method/AdapterTest.php b/app/code/Magento/Payment/Test/Unit/Model/Method/AdapterTest.php index b5229b57875..d8fefb7345e 100644 --- a/app/code/Magento/Payment/Test/Unit/Model/Method/AdapterTest.php +++ b/app/code/Magento/Payment/Test/Unit/Model/Method/AdapterTest.php @@ -13,9 +13,12 @@ use Magento\Payment\Gateway\Config\ValueHandlerInterface; use Magento\Payment\Gateway\Config\ValueHandlerPoolInterface; use Magento\Payment\Gateway\Data\PaymentDataObjectFactory; use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; +use Magento\Payment\Gateway\Validator\ResultInterface; +use Magento\Payment\Gateway\Validator\ValidatorInterface; use Magento\Payment\Gateway\Validator\ValidatorPoolInterface; use Magento\Payment\Model\InfoInterface; use Magento\Payment\Model\Method\Adapter; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -23,27 +26,27 @@ use Magento\Payment\Model\Method\Adapter; class AdapterTest extends \PHPUnit_Framework_TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject | ManagerInterface + * @var MockObject|ManagerInterface */ private $eventManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject | ValueHandlerPoolInterface + * @var MockObject|ValueHandlerPoolInterface */ private $valueHandlerPool; /** - * @var \PHPUnit_Framework_MockObject_MockObject | ValidatorPoolInterface + * @var MockObject|ValidatorPoolInterface */ private $validatorPool; /** - * @var \PHPUnit_Framework_MockObject_MockObject | CommandPoolInterface + * @var MockObject|CommandPoolInterface */ private $commandPool; /** - * @var \PHPUnit_Framework_MockObject_MockObject | PaymentDataObjectFactory + * @var MockObject|PaymentDataObjectFactory */ private $paymentDataObjectFactory; @@ -69,21 +72,11 @@ class AdapterTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->eventManager = $this->getMock( - \Magento\Framework\Event\ManagerInterface::class - ); - $this->valueHandlerPool = $this->getMock( - \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface::class - ); - $this->validatorPool = $this->getMock( - \Magento\Payment\Gateway\Validator\ValidatorPoolInterface::class - ); - $this->commandPool = $this->getMock( - \Magento\Payment\Gateway\Command\CommandPoolInterface::class - ); - $this->paymentDataObjectFactory = $this->getMockBuilder( - \Magento\Payment\Gateway\Data\PaymentDataObjectFactory::class - ) + $this->eventManager = $this->getMock(ManagerInterface::class); + $this->valueHandlerPool = $this->getMock(ValueHandlerPoolInterface::class); + $this->validatorPool = $this->getMock(ValidatorPoolInterface::class); + $this->commandPool = $this->getMock(CommandPoolInterface::class); + $this->paymentDataObjectFactory = $this->getMockBuilder(PaymentDataObjectFactory::class) ->disableOriginalConstructor() ->getMock(); @@ -103,11 +96,12 @@ class AdapterTest extends \PHPUnit_Framework_TestCase ); } + /** + * @covers \Magento\Payment\Model\Method\Adapter::isAvailable + */ public function testIsAvailableNotActive() { - $activeValueHandler = $this->getMock( - \Magento\Payment\Gateway\Config\ValueHandlerInterface::class - ); + $activeValueHandler = $this->getMock(ValueHandlerInterface::class); $this->valueHandlerPool->expects(static::once()) ->method('get') @@ -124,17 +118,16 @@ class AdapterTest extends \PHPUnit_Framework_TestCase static::assertFalse($this->adapter->isAvailable(null)); } + /** + * @covers \Magento\Payment\Model\Method\Adapter::isAvailable + */ public function testIsAvailableEmptyQuote() { - $activeValueHandler = $this->getMock( - \Magento\Payment\Gateway\Config\ValueHandlerInterface::class - ); - $availabilityValidator = $this->getMock( - \Magento\Payment\Gateway\Validator\ValidatorInterface::class - ); - $paymentDO = $this->getMock(\Magento\Payment\Gateway\Data\PaymentDataObjectInterface::class); - $validationResult = $this->getMock(\Magento\Payment\Gateway\Validator\ResultInterface::class); - $paymentInfo = $this->getMock(\Magento\Payment\Model\InfoInterface::class); + $activeValueHandler = $this->getMock(ValueHandlerInterface::class); + $availabilityValidator = $this->getMock(ValidatorInterface::class); + $paymentDO = $this->getMock(PaymentDataObjectInterface::class); + $validationResult = $this->getMock(ResultInterface::class); + $paymentInfo = $this->getMock(InfoInterface::class); $this->valueHandlerPool->expects(static::once()) ->method('get') @@ -167,24 +160,49 @@ class AdapterTest extends \PHPUnit_Framework_TestCase static::assertTrue($this->adapter->isAvailable(null)); } + /** + * @covers \Magento\Payment\Model\Method\Adapter::isAvailable + */ + public function testIsAvailableWithEmptyInfoInstance() + { + $activeValueHandler = $this->getMock(ValueHandlerInterface::class); + $this->valueHandlerPool->expects(static::once()) + ->method('get') + ->with('active') + ->willReturn($activeValueHandler); + $activeValueHandler->expects(static::once()) + ->method('handle') + ->with(['field' => 'active']) + ->willReturn(true); + + $this->validatorPool->expects(static::never()) + ->method('get') + ->with('availability'); + + $this->eventManager->expects(static::once()) + ->method('dispatch'); + + static::assertTrue($this->adapter->isAvailable(null)); + } + public function testExecuteCommandWithCommandExecutor() { - /** @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject $eventManager */ + /** @var ManagerInterface|MockObject $eventManager */ $eventManager = $this->getMock( ManagerInterface::class ); - /** @var ValueHandlerPoolInterface|\PHPUnit_Framework_MockObject_MockObject $valueHandlerPool */ + /** @var ValueHandlerPoolInterface|MockObject $valueHandlerPool */ $valueHandlerPool = $this->getMock( ValueHandlerPoolInterface::class ); - /** @var CommandManagerInterface|\PHPUnit_Framework_MockObject_MockObject $commandManager */ + /** @var CommandManagerInterface|MockObject $commandManager */ $commandManager = $this->getMock( CommandManagerInterface::class ); - /** @var PaymentDataObjectFactory|\PHPUnit_Framework_MockObject_MockObject $paymentDataObjectFactory */ + /** @var PaymentDataObjectFactory|MockObject $paymentDataObjectFactory */ $paymentDataObjectFactory = $this->getMockBuilder( PaymentDataObjectFactory::class ) @@ -232,25 +250,17 @@ class AdapterTest extends \PHPUnit_Framework_TestCase public function testExecuteCommandWithCommandPool() { - /** @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject $eventManager */ - $eventManager = $this->getMock( - ManagerInterface::class - ); + /** @var ManagerInterface|MockObject $eventManager */ + $eventManager = $this->getMock(ManagerInterface::class); - /** @var ValueHandlerPoolInterface|\PHPUnit_Framework_MockObject_MockObject $valueHandlerPool */ - $valueHandlerPool = $this->getMock( - ValueHandlerPoolInterface::class - ); + /** @var ValueHandlerPoolInterface|MockObject $valueHandlerPool */ + $valueHandlerPool = $this->getMock(ValueHandlerPoolInterface::class); - /** @var CommandPoolInterface|\PHPUnit_Framework_MockObject_MockObject $commandPool */ - $commandPool = $this->getMock( - CommandPoolInterface::class - ); + /** @var CommandPoolInterface|MockObject $commandPool */ + $commandPool = $this->getMock(CommandPoolInterface::class); - /** @var PaymentDataObjectFactory|\PHPUnit_Framework_MockObject_MockObject $paymentDataObjectFactory */ - $paymentDataObjectFactory = $this->getMockBuilder( - PaymentDataObjectFactory::class - ) + /** @var PaymentDataObjectFactory|MockObject $paymentDataObjectFactory */ + $paymentDataObjectFactory = $this->getMockBuilder(PaymentDataObjectFactory::class) ->disableOriginalConstructor() ->getMock(); -- GitLab From b04c4bf7fa286fc8c82cf5418697d2f706e1a910 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Mon, 8 Aug 2016 17:39:59 +0300 Subject: [PATCH 199/838] MAGETWO-55268: Upgrade/Check Requirements process --- setup/pub/magento/setup/readiness-check.js | 14 +++-- setup/pub/magento/setup/remove-dialog.js | 16 +++++ setup/view/layout/layout.phtml | 1 + .../setup/readiness-check/progress.phtml | 61 +++++++++++++++++-- 4 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 setup/pub/magento/setup/remove-dialog.js diff --git a/setup/pub/magento/setup/readiness-check.js b/setup/pub/magento/setup/readiness-check.js index b967d4c066c..ec3d2c9352f 100644 --- a/setup/pub/magento/setup/readiness-check.js +++ b/setup/pub/magento/setup/readiness-check.js @@ -4,9 +4,9 @@ */ 'use strict'; -angular.module('readiness-check', []) +angular.module('readiness-check', ['remove-dialog']) .constant('COUNTER', 1) - .controller('readinessCheckController', ['$rootScope', '$scope', '$localStorage', '$http', '$timeout', '$sce', '$state', 'COUNTER', function ($rootScope, $scope, $localStorage, $http, $timeout, $sce, $state, COUNTER) { + .controller('readinessCheckController', ['$rootScope', '$scope', '$localStorage', '$http', '$timeout', '$sce', '$state', 'COUNTER', 'ngDialog', function ($rootScope, $scope, $localStorage, $http, $timeout, $sce, $state, COUNTER, ngDialog) { $scope.Object = Object; $scope.titles = $localStorage.titles; $scope.moduleName = $localStorage.moduleName; @@ -362,6 +362,9 @@ angular.module('readiness-check', []) } } else { $actionString += 'package'; + if ($scope.getObjectSize($localStorage.packages) > 1) { + $actionString += 's'; + } } } $actionString += " to be " + $state.current.type; @@ -377,10 +380,9 @@ angular.module('readiness-check', []) return $scope.componentDependency.packages ? $scope.componentDependency.packages : {}; }; - $scope.removeExtension = function (name) { - delete $scope.componentDependency.packages[name]; - $localStorage.packages = $scope.componentDependency.packages; - $rootScope.needReCheck = true; + $scope.openDialog = function (name) { + $scope.extensionToRemove = name; + ngDialog.open({scope: $scope, template: 'removeDialog', controller: 'removeDialogController'}); }; $scope.getCurrentVersion = function (name) { diff --git a/setup/pub/magento/setup/remove-dialog.js b/setup/pub/magento/setup/remove-dialog.js new file mode 100644 index 00000000000..96a63ec5193 --- /dev/null +++ b/setup/pub/magento/setup/remove-dialog.js @@ -0,0 +1,16 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +'use strict'; +angular.module('remove-dialog', []) + .controller('removeDialogController', ['$rootScope', '$scope', '$localStorage', + function ($rootScope, $scope, $localStorage) { + $scope.removeExtension = function (name) { + delete $scope.componentDependency.packages[name]; + $localStorage.packages = $scope.componentDependency.packages; + $rootScope.needReCheck = true; + $scope.closeThisDialog(); + }; + }]); diff --git a/setup/view/layout/layout.phtml b/setup/view/layout/layout.phtml index f4f137c2263..591da1f16f9 100644 --- a/setup/view/layout/layout.phtml +++ b/setup/view/layout/layout.phtml @@ -45,6 +45,7 @@ ->appendFile($this->basePath() . '/pub/magento/setup/select-version.js') ->appendFile($this->basePath() . '/pub/magento/setup/home.js') ->appendFile($this->basePath() . '/pub/magento/setup/auth-dialog.js') + ->appendFile($this->basePath() . '/pub/magento/setup/remove-dialog.js') ->appendFile($this->basePath() . '/pub/magento/setup/system-config.js') ->appendFile($this->basePath() . '/pub/magento/setup/marketplace-credentials.js') ->appendFile($this->basePath() . '/pub/magento/setup/install-extension-grid.js') diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index b47bc7b5cb3..4634e9efaa4 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -7,15 +7,24 @@ // @codingStandardsIgnoreFile ?> -<div class="message" ng-class="{'message-warning':needReCheck && !checkingInProgress()}" - ng-show="getObjectSize(getExtensionsList()) > 0" +<style> + .top-ico:before { + margin-top: 0; + top: 1.8rem; + } + .list select:disabled { + background: #cccccc; + } +</style> +<div class="message top-ico" ng-class="{'message-warning':needReCheck && !checkingInProgress()}" + ng-if="$state.current.type == 'update' && getObjectSize(getExtensionsList()) > 0" > - <div><strong>Extensions to {{$state.current.type}}:</strong></div> - <div>You can change the version or remove the extension from the updating.</div> + <h3>Extensions to {{$state.current.type}}:</h3> + <div style="padding: 0 0 2rem 0;">You can change the version or remove the extension from the updating.</div> <ul class="list"> <li ng-repeat="extension in getExtensionsList()"> - {{extension.name}} {{getCurrentVersion(extension.name)}} to + <strong>{{extension.name}} {{getCurrentVersion(extension.name)}}</strong> to <select ng-change="versionChanged()" ng-model="extension.version" ng-disabled="checkingInProgress()" @@ -26,7 +35,7 @@ >Version {{version}}</option> </select> <button style="padding-top: 0;" class="abs-action-delete" - ng-click="removeExtension(extension.name)" + ng-click="openDialog(extension.name)" ng-show="!checkingInProgress() && getObjectSize(getExtensionsList()) > 1"></button> </li> </ul> @@ -526,3 +535,43 @@ <div class="readiness-check-item" id="warning-message" ng-show="true"> * - In some cases, you might have two PHP configuration files: one for the PHP command line and for the web server. If so, make the change in both php.ini files. For details, see the <a href="http://php.net/manual/en/configuration.file.php">php.ini reference</a>. </div> + +<script type="text/ng-template" id="removeDialog"> + <div class="modals-wrapper"> + <aside class="modal-popup modal-connect-signin _show" data-role="modal"> + <div class="modal-inner-wrap"> + <header class="modal-header"> + <button ng-click="closeThisDialog()" class="action-close" data-role="closeBtn" type="button"> + <span>Close</span> + </button> + </header> + <div class="modal-content" data-role="content"> + <div class="sync-login-wrap" style="padding: 0 4% 4rem;"> + <div class="login-header"> + <span>Remove Product</span> + </div> + + <div>Are you sure you want to remove “{{extensionToRemove}}†from + the list?</div> + <br> + <div> + Please be aware that removing this product will remove it from the current + update wizard flow. You can update this product at a later time by selecting + the product in the update grid. + </div> + <div class="form-actions"> + <div class="actions" style="padding: 5rem 0 0;"> + <button ng-click="removeExtension(extensionToRemove)" class="btn btn-large btn-prime"> + <span>Remove</span> + </button> + <button ng-click="closeThisDialog()" class="btn btn-large btn-cancel"> + <span>Cancel</span> + </button> + </div> + </div> + </div> + </div> + </div> + </aside> + </div> +</script> \ No newline at end of file -- GitLab From 0b29e79f705411861302b32f1f602237cd1572e3 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Mon, 8 Aug 2016 19:29:21 +0300 Subject: [PATCH 200/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales, SalesRule modules --- .../Sales/Model/Order/AddressRepository.php | 42 +++++++--- .../Model/Order/CreditmemoRepository.php | 37 ++++++--- .../Sales/Model/Order/InvoiceRepository.php | 37 ++++++--- .../Sales/Model/Order/ItemRepository.php | 37 ++++++--- .../Sales/Model/Order/Payment/Repository.php | 39 ++++++--- .../Order/Payment/Transaction/Repository.php | 37 ++++++--- .../Sales/Model/Order/ShipmentRepository.php | 38 ++++++--- .../Magento/Sales/Model/OrderRepository.php | 47 ++++++----- .../Order/Address/Collection.php | 5 +- .../ResourceModel/Order/Item/Collection.php | 4 +- .../Test/Unit/Model/InvoiceRepositoryTest.php | 47 ++++------- .../Model/Order/AddressRepositoryTest.php | 54 ++++--------- .../Model/Order/CreditmemoRepositoryTest.php | 46 +++-------- .../Unit/Model/Order/ItemRepositoryTest.php | 67 ++++++--------- .../Model/Order/Payment/RepositoryTest.php | 41 ++++------ .../Payment/Transaction/RepositoryTest.php | 39 ++++----- .../Model/Order/ShipmentRepositoryTest.php | 58 +++++-------- .../Test/Unit/Model/OrderRepositoryTest.php | 38 ++++----- .../SalesRule/Model/CouponRepository.php | 51 ++++++------ .../SalesRule/Model/RuleRepository.php | 59 +++++++------- .../Test/Unit/Model/CouponRepositoryTest.php | 44 +++++----- .../Test/Unit/Model/RuleRepositoryTest.php | 41 ++++------ .../Unit/Model/PaymentTokenRepositoryTest.php | 5 +- .../Sales/Service/V1/CreditmemoListTest.php | 42 +++++++--- .../Sales/Service/V1/InvoiceListTest.php | 43 +++++++--- .../Sales/Service/V1/OrderItemGetListTest.php | 42 +++++++--- .../Sales/Service/V1/OrderListTest.php | 41 +++++++--- .../Sales/Service/V1/ShipmentListTest.php | 40 ++++++--- .../Sales/Service/V1/TransactionTest.php | 41 ++++++++-- .../SalesRule/Api/CouponRepositoryTest.php | 70 ++++++++++++++++ .../SalesRule/Api/RuleRepositoryTest.php | 72 +++++++++++++++++ .../Model/Order/AddressRepositoryTest.php | 81 +++++++++++++++++++ .../Model/Order/Payment/RepositoryTest.php | 80 ++++++++++++++++++ .../Magento/Sales/_files/address_list.php | 67 +++++++++++++++ .../Sales/_files/address_list_rollback.php | 7 ++ .../Magento/Sales/_files/creditmemo_list.php | 63 +++++++++++++++ .../Sales/_files/creditmemo_list_rollback.php | 7 ++ .../Magento/Sales/_files/invoice_list.php | 63 +++++++++++++++ .../Sales/_files/invoice_list_rollback.php | 7 ++ .../Magento/Sales/_files/order_item_list.php | 57 +++++++++++++ .../Magento/Sales/_files/order_list.php | 54 +++++++++++++ .../Sales/_files/order_list_rollback.php | 9 +++ .../Sales/_files/order_payment_list.php | 50 ++++++++++++ .../Magento/Sales/_files/shipment_list.php | 60 ++++++++++++++ .../Sales/_files/shipment_list_rollback.php | 7 ++ .../Sales/_files/transactions_list.php | 56 +++++++++++++ .../_files/transactions_list_rollback.php | 7 ++ .../Magento/SalesRule/_files/coupons.php | 8 +- .../Magento/SalesRule/_files/rules.php | 14 +++- .../SalesRule/_files/rules_rollback.php | 15 ++++ .../Model/PaymentTokenRepositoryTest.php | 2 +- .../Magento/Vault/_files/payment_tokens.php | 2 +- 52 files changed, 1498 insertions(+), 522 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Model/Order/AddressRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Model/Order/Payment/RepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/address_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/address_list_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_item_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/order_payment_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_rollback.php diff --git a/app/code/Magento/Sales/Model/Order/AddressRepository.php b/app/code/Magento/Sales/Model/Order/AddressRepository.php index e075d4afdcd..c38d7bed1e7 100644 --- a/app/code/Magento/Sales/Model/Order/AddressRepository.php +++ b/app/code/Magento/Sales/Model/Order/AddressRepository.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model\Order; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Sales\Model\ResourceModel\Metadata; use Magento\Sales\Api\Data\OrderAddressSearchResultInterfaceFactory as SearchResultFactory; use Magento\Framework\Exception\CouldNotDeleteException; @@ -34,16 +35,23 @@ class AddressRepository implements \Magento\Sales\Api\OrderAddressRepositoryInte */ protected $registry = []; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** + * AddressRepository constructor. * @param Metadata $metadata * @param SearchResultFactory $searchResultFactory + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( Metadata $metadata, - SearchResultFactory $searchResultFactory + SearchResultFactory $searchResultFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->metadata = $metadata; $this->searchResultFactory = $searchResultFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -81,19 +89,11 @@ class AddressRepository implements \Magento\Sales\Api\OrderAddressRepositoryInte */ public function getList(\Magento\Framework\Api\SearchCriteria $searchCriteria) { - //@TODO: fix search logic - /** @var \Magento\Sales\Api\Data\OrderAddressSearchResultInterface $searchResult */ + /** @var \Magento\Sales\Model\ResourceModel\Order\Address\Collection $searchResult */ $searchResult = $this->searchResultFactory->create(); - - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $searchResult->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } - $searchResult->setCurPage($searchCriteria->getCurrentPage()); - $searchResult->setPageSize($searchCriteria->getPageSize()); - + $this->collectionProcessor->process($searchCriteria, $searchResult); + $searchResult->setSearchCriteria($searchCriteria); + return $searchResult; } @@ -158,4 +158,20 @@ class AddressRepository implements \Magento\Sales\Api\OrderAddressRepositoryInte { return $this->metadata->getNewInstance(); } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoRepository.php b/app/code/Magento/Sales/Model/Order/CreditmemoRepository.php index fb131533303..3fc0a2a4da4 100644 --- a/app/code/Magento/Sales/Model/Order/CreditmemoRepository.php +++ b/app/code/Magento/Sales/Model/Order/CreditmemoRepository.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model\Order; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Sales\Model\ResourceModel\Order\Creditmemo as Resource; use Magento\Sales\Model\ResourceModel\Metadata; use Magento\Sales\Api\Data\CreditmemoSearchResultInterfaceFactory as SearchResultFactory; @@ -37,16 +38,23 @@ class CreditmemoRepository implements \Magento\Sales\Api\CreditmemoRepositoryInt */ protected $registry = []; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** + * CreditmemoRepository constructor. * @param Metadata $metadata * @param SearchResultFactory $searchResultFactory + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( Metadata $metadata, - SearchResultFactory $searchResultFactory + SearchResultFactory $searchResultFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->metadata = $metadata; $this->searchResultFactory = $searchResultFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -91,17 +99,10 @@ class CreditmemoRepository implements \Magento\Sales\Api\CreditmemoRepositoryInt */ public function getList(\Magento\Framework\Api\SearchCriteria $searchCriteria) { - /** @var \Magento\Sales\Api\Data\CreditmemoSearchResultInterface $searchResult */ + /** @var \Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection $searchResult */ $searchResult = $this->searchResultFactory->create(); - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $searchResult->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } + $this->collectionProcessor->process($searchCriteria, $searchResult); $searchResult->setSearchCriteria($searchCriteria); - $searchResult->setCurPage($searchCriteria->getCurrentPage()); - $searchResult->setPageSize($searchCriteria->getPageSize()); return $searchResult; } @@ -140,4 +141,20 @@ class CreditmemoRepository implements \Magento\Sales\Api\CreditmemoRepositoryInt } return $this->registry[$entity->getEntityId()]; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/Order/InvoiceRepository.php b/app/code/Magento/Sales/Model/Order/InvoiceRepository.php index 38cd7bdc97f..0a22f7d6a05 100644 --- a/app/code/Magento/Sales/Model/Order/InvoiceRepository.php +++ b/app/code/Magento/Sales/Model/Order/InvoiceRepository.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model\Order; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Sales\Api\InvoiceRepositoryInterface; use Magento\Sales\Model\ResourceModel\Metadata; use Magento\Framework\Exception\NoSuchEntityException; @@ -33,18 +34,23 @@ class InvoiceRepository implements InvoiceRepositoryInterface */ protected $searchResultFactory; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** - * Repository constructor - * + * InvoiceRepository constructor. * @param Metadata $invoiceMetadata * @param SearchResultFactory $searchResultFactory + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( Metadata $invoiceMetadata, - SearchResultFactory $searchResultFactory + SearchResultFactory $searchResultFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->metadata = $invoiceMetadata; $this->searchResultFactory = $searchResultFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -89,15 +95,8 @@ class InvoiceRepository implements InvoiceRepositoryInterface { /** @var \Magento\Sales\Model\ResourceModel\Order\Invoice\Collection $collection */ $collection = $this->searchResultFactory->create(); - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } + $this->collectionProcessor->process($searchCriteria, $collection); $collection->setSearchCriteria($searchCriteria); - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); return $collection; } @@ -138,4 +137,20 @@ class InvoiceRepository implements InvoiceRepositoryInterface $this->registry[$entity->getEntityId()] = $entity; return $this->registry[$entity->getEntityId()]; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/Order/ItemRepository.php b/app/code/Magento/Sales/Model/Order/ItemRepository.php index 65c53c8d69a..8fdeca7eb7d 100644 --- a/app/code/Magento/Sales/Model/Order/ItemRepository.php +++ b/app/code/Magento/Sales/Model/Order/ItemRepository.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model\Order; use Magento\Catalog\Api\Data\ProductOptionExtensionFactory; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Catalog\Model\ProductOptionFactory; use Magento\Catalog\Model\ProductOptionProcessorInterface; use Magento\Framework\Api\SearchCriteria; @@ -60,13 +61,18 @@ class ItemRepository implements OrderItemRepositoryInterface */ protected $registry = []; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** + * ItemRepository constructor. * @param DataObjectFactory $objectFactory * @param Metadata $metadata * @param OrderItemSearchResultInterfaceFactory $searchResultFactory * @param ProductOptionFactory $productOptionFactory * @param ProductOptionExtensionFactory $extensionFactory * @param array $processorPool + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( DataObjectFactory $objectFactory, @@ -74,7 +80,8 @@ class ItemRepository implements OrderItemRepositoryInterface OrderItemSearchResultInterfaceFactory $searchResultFactory, ProductOptionFactory $productOptionFactory, ProductOptionExtensionFactory $extensionFactory, - array $processorPool = [] + array $processorPool = [], + CollectionProcessorInterface $collectionProcessor = null ) { $this->objectFactory = $objectFactory; $this->metadata = $metadata; @@ -82,6 +89,7 @@ class ItemRepository implements OrderItemRepositoryInterface $this->productOptionFactory = $productOptionFactory; $this->extensionFactory = $extensionFactory; $this->processorPool = $processorPool; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -118,17 +126,10 @@ class ItemRepository implements OrderItemRepositoryInterface */ public function getList(SearchCriteria $searchCriteria) { - /** @var OrderItemSearchResultInterface $searchResult */ + /** @var \Magento\Sales\Model\ResourceModel\Order\Item\Collection $searchResult */ $searchResult = $this->searchResultFactory->create(); $searchResult->setSearchCriteria($searchCriteria); - - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $searchResult->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } - + $this->collectionProcessor->process($searchCriteria, $searchResult); /** @var OrderItemInterface $orderItem */ foreach ($searchResult->getItems() as $orderItem) { $this->addProductOption($orderItem); @@ -268,4 +269,20 @@ class ItemRepository implements OrderItemRepositoryInterface return $request; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/Order/Payment/Repository.php b/app/code/Magento/Sales/Model/Order/Payment/Repository.php index c4a1cea24da..04125628237 100644 --- a/app/code/Magento/Sales/Model/Order/Payment/Repository.php +++ b/app/code/Magento/Sales/Model/Order/Payment/Repository.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Model\Order\Payment; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\OrderPaymentRepositoryInterface; use Magento\Sales\Model\ResourceModel\Metadata; @@ -34,14 +35,22 @@ class Repository implements OrderPaymentRepositoryInterface */ protected $searchResultFactory; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * @param Metadata $metaData * @param SearchResultFactory $searchResultFactory + * @param CollectionProcessorInterface $collectionProcessor */ - public function __construct(Metadata $metaData, SearchResultFactory $searchResultFactory) - { + public function __construct( + Metadata $metaData, + SearchResultFactory $searchResultFactory, + CollectionProcessorInterface $collectionProcessor = null + ) { $this->metaData = $metaData; $this->searchResultFactory = $searchResultFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -54,14 +63,8 @@ class Repository implements OrderPaymentRepositoryInterface { /** @var \Magento\Sales\Model\ResourceModel\Order\Payment\Collection $collection */ $collection = $this->searchResultFactory->create(); - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $collection->setSearchCriteria($searchCriteria); + $this->collectionProcessor->process($searchCriteria, $collection); return $collection; } @@ -121,4 +124,20 @@ class Repository implements OrderPaymentRepositoryInterface { return $this->metaData->getNewInstance(); } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php index 687260cb185..c9743805ac1 100644 --- a/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php +++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Model\Order\Payment\Transaction; use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Data\Collection; @@ -60,15 +61,18 @@ class Repository implements TransactionRepositoryInterface */ private $entityStorage; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** - * Repository constructor - * + * Repository constructor. * @param SearchResultFactory $searchResultFactory * @param FilterBuilder $filterBuilder * @param SearchCriteriaBuilder $searchCriteriaBuilder * @param SortOrderBuilder $sortOrderBuilder * @param Metadata $metaData * @param EntityStorageFactory $entityStorageFactory + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( SearchResultFactory $searchResultFactory, @@ -76,7 +80,8 @@ class Repository implements TransactionRepositoryInterface SearchCriteriaBuilder $searchCriteriaBuilder, SortOrderBuilder $sortOrderBuilder, Metadata $metaData, - EntityStorageFactory $entityStorageFactory + EntityStorageFactory $entityStorageFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->searchResultFactory = $searchResultFactory; $this->filterBuilder = $filterBuilder; @@ -84,6 +89,7 @@ class Repository implements TransactionRepositoryInterface $this->sortOrderBuilder = $sortOrderBuilder; $this->metaData = $metaData; $this->entityStorage = $entityStorageFactory->create(); + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -187,15 +193,8 @@ class Repository implements TransactionRepositoryInterface { /** @var TransactionResource\Collection $collection */ $collection = $this->searchResultFactory->create(); - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $collection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } $collection->setSearchCriteria($searchCriteria); - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $this->collectionProcessor->process($searchCriteria, $collection); $collection->addPaymentInformation(['method']); $collection->addOrderInformation(['increment_id']); return $collection; @@ -230,4 +229,20 @@ class Repository implements TransactionRepositoryInterface { return $this->metaData->getNewInstance(); } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/Order/ShipmentRepository.php b/app/code/Magento/Sales/Model/Order/ShipmentRepository.php index d32a5f83f2d..2ddff08d900 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentRepository.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentRepository.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model\Order; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Sales\Model\ResourceModel\Metadata; use Magento\Sales\Api\Data\ShipmentSearchResultInterfaceFactory as SearchResultFactory; use Magento\Framework\Exception\CouldNotDeleteException; @@ -34,16 +35,22 @@ class ShipmentRepository implements \Magento\Sales\Api\ShipmentRepositoryInterfa */ protected $registry = []; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * @param Metadata $metadata * @param SearchResultFactory $searchResultFactory + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( Metadata $metadata, - SearchResultFactory $searchResultFactory + SearchResultFactory $searchResultFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->metadata = $metadata; $this->searchResultFactory = $searchResultFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -81,19 +88,10 @@ class ShipmentRepository implements \Magento\Sales\Api\ShipmentRepositoryInterfa */ public function getList(\Magento\Framework\Api\SearchCriteria $searchCriteria) { - //@TODO: fix search logic - /** @var \Magento\Sales\Api\Data\ShipmentSearchResultInterface $searchResult */ + /** @var \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection $searchResult */ $searchResult = $this->searchResultFactory->create(); - - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $searchResult->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); - } - } + $this->collectionProcessor->process($searchCriteria, $searchResult); $searchResult->setSearchCriteria($searchCriteria); - $searchResult->setCurPage($searchCriteria->getCurrentPage()); - $searchResult->setPageSize($searchCriteria->getPageSize()); return $searchResult; } @@ -159,4 +157,20 @@ class ShipmentRepository implements \Magento\Sales\Api\ShipmentRepositoryInterfa { return $this->metadata->getNewInstance(); } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/OrderRepository.php b/app/code/Magento/Sales/Model/OrderRepository.php index b83ab5ff469..5c14b3fd443 100644 --- a/app/code/Magento/Sales/Model/OrderRepository.php +++ b/app/code/Magento/Sales/Model/OrderRepository.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Sales\Model\ResourceModel\Order as Resource; use Magento\Sales\Model\ResourceModel\Metadata; use Magento\Sales\Model\Order\ShippingAssignmentBuilder; @@ -43,6 +44,9 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface */ private $shippingAssignmentBuilder; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** * OrderInterface[] * @@ -52,16 +56,18 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface /** * OrderRepository constructor. - * * @param Metadata $metadata * @param SearchResultFactory $searchResultFactory + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( Metadata $metadata, - SearchResultFactory $searchResultFactory + SearchResultFactory $searchResultFactory, + CollectionProcessorInterface $collectionProcessor = null ) { $this->metadata = $metadata; $this->searchResultFactory = $searchResultFactory; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -99,26 +105,8 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface { /** @var \Magento\Sales\Api\Data\OrderSearchResultInterface $searchResult */ $searchResult = $this->searchResultFactory->create(); - foreach ($searchCriteria->getFilterGroups() as $filterGroup) { - $this->addFilterGroupToCollection($filterGroup, $searchResult); - } - - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders === null) { - $sortOrders = []; - } - /** @var \Magento\Framework\Api\SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $field = $sortOrder->getField(); - $searchResult->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - + $this->collectionProcessor->process($searchCriteria, $searchResult); $searchResult->setSearchCriteria($searchCriteria); - $searchResult->setCurPage($searchCriteria->getCurrentPage()); - $searchResult->setPageSize($searchCriteria->getPageSize()); foreach ($searchResult->getItems() as $order) { $this->setShippingAssignments($order); } @@ -222,6 +210,7 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup * @param \Magento\Sales\Api\Data\OrderSearchResultInterface $searchResult * @return void + * @deprecated * @throws \Magento\Framework\Exception\InputException */ protected function addFilterGroupToCollection( @@ -239,4 +228,20 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface $searchResult->addFieldToFilter($fields, $conditions); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Address/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Address/Collection.php index de54cfaff9a..59f17925a0b 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Address/Collection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Address/Collection.php @@ -5,12 +5,15 @@ */ namespace Magento\Sales\Model\ResourceModel\Order\Address; +use Magento\Sales\Api\Data\OrderAddressSearchResultInterface; +use \Magento\Sales\Model\ResourceModel\Order\Collection\AbstractCollection; + /** * Flat sales order payment collection * * @author Magento Core Team <core@magentocommerce.com> */ -class Collection extends \Magento\Sales\Model\ResourceModel\Order\Collection\AbstractCollection +class Collection extends AbstractCollection implements OrderAddressSearchResultInterface { /** * Event prefix diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Item/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Item/Collection.php index 7559bae68ff..d38c0dbc58b 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Item/Collection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Item/Collection.php @@ -5,12 +5,14 @@ */ namespace Magento\Sales\Model\ResourceModel\Order\Item; +use \Magento\Sales\Model\ResourceModel\Order\Collection\AbstractCollection; + /** * Flat sales order payment collection * * @author Magento Core Team <core@magentocommerce.com> */ -class Collection extends \Magento\Sales\Model\ResourceModel\Order\Collection\AbstractCollection +class Collection extends AbstractCollection implements \Magento\Sales\Api\Data\OrderItemSearchResultInterface { /** * Event prefix diff --git a/app/code/Magento/Sales/Test/Unit/Model/InvoiceRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/InvoiceRepositoryTest.php index 964974507d1..5c3d970d42f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/InvoiceRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/InvoiceRepositoryTest.php @@ -6,6 +6,8 @@ namespace Magento\Sales\Test\Unit\Model; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; + /** * Class InvoiceRepositoryTest */ @@ -26,6 +28,11 @@ class InvoiceRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $searchResultFactory; + /** + * @var CollectionProcessorInterface |\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -36,11 +43,14 @@ class InvoiceRepositoryTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); $this->invoice = $objectManager->getObject( \Magento\Sales\Model\Order\InvoiceRepository::class, [ 'invoiceMetadata' => $this->invoiceMetadata, - 'searchResultFactory' => $this->searchResultFactory + 'searchResultFactory' => $this->searchResultFactory, + 'collectionProcessor' => $this->collectionProcessorMock, ] ); $this->type = $this->getMock(\Magento\Eav\Model\Entity\Type::class, ['fetchNewIncrementId'], [], '', false); @@ -116,44 +126,15 @@ class InvoiceRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $filterGroup = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class) - ->disableOriginalConstructor() - ->getMock(); - $filterGroups = [$filterGroup]; - $field = 'test_field'; - $fieldValue = 'test_value'; - - $filter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filter->expects($this->any()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->any()) - ->method('getField') - ->willReturn($field); - $filter->expects($this->any()) - ->method('getValue') - ->willReturn($fieldValue); - - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $searchCriteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteria::class) ->disableOriginalConstructor() ->getMock(); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn($filterGroups); - $collection = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Invoice\Collection::class) ->disableOriginalConstructor() ->getMock(); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->withAnyParameters(); - + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $this->searchResultFactory->expects($this->once()) ->method('create') ->willReturn($collection); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/AddressRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/AddressRepositoryTest.php index d99100f3c80..d1aa65afd50 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/AddressRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/AddressRepositoryTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Test\Unit\Model\Order; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; /** @@ -33,6 +34,11 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $searchResultFactory; + /** + * @var CollectionProcessorInterface |\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + protected function setUp() { $objectManager = new ObjectManager($this); @@ -53,11 +59,15 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase false ); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); + $this->subject = $objectManager->getObject( \Magento\Sales\Model\Order\AddressRepository::class, [ 'metadata' => $this->metadata, - 'searchResultFactory' => $this->searchResultFactory + 'searchResultFactory' => $this->searchResultFactory, + 'collectionProcessor' => $this->collectionProcessorMock, ] ); } @@ -136,56 +146,24 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $filter = $this->getMock( - \Magento\Framework\Api\Filter::class, - ['getConditionType', 'getField', 'getValue'], - [], - '', - false - ); - $filter->expects($this->any()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->any()) - ->method('getField') - ->willReturn('test_field'); - $filter->expects($this->any()) - ->method('getValue') - ->willReturn('test_value'); - - $filterGroup = $this->getMock( - \Magento\Framework\Api\Search\FilterGroup::class, - ['getFilters'], - [], - '', - false - ); - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $searchCriteria = $this->getMock( \Magento\Framework\Api\SearchCriteria::class, - ['getFilterGroups'], + [], [], '', false ); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroup]); - $collection = $this->getMock( \Magento\Sales\Model\ResourceModel\Order\Address\Collection::class, - ['addFieldToFilter'], + [], [], '', false ); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->withAnyParameters(); + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $this->searchResultFactory->expects($this->once()) ->method('create') ->willReturn($collection); diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoRepositoryTest.php index 3bbf663bd2d..52dc60dc70d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/CreditmemoRepositoryTest.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Test\Unit\Model\Order; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use \Magento\Sales\Model\Order\CreditmemoRepository; /** @@ -29,6 +30,11 @@ class CreditmemoRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $searchResultFactoryMock; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -40,11 +46,14 @@ class CreditmemoRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); $this->creditmemo = $objectManager->getObject( \Magento\Sales\Model\Order\CreditmemoRepository::class, [ 'metadata' => $this->metadataMock, - 'searchResultFactory' => $this->searchResultFactoryMock + 'searchResultFactory' => $this->searchResultFactoryMock, + 'collectionProcessor' => $this->collectionProcessorMock, ] ); $this->type = $this->getMock(\Magento\Eav\Model\Entity\Type::class, ['fetchNewIncrementId'], [], '', false); @@ -120,44 +129,15 @@ class CreditmemoRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $filterGroup = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class) - ->disableOriginalConstructor() - ->getMock(); - $filterGroups = [$filterGroup]; - $field = 'test_field'; - $fieldValue = 'test_value'; - - $filter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filter->expects($this->any()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->any()) - ->method('getField') - ->willReturn($field); - $filter->expects($this->any()) - ->method('getValue') - ->willReturn($fieldValue); - - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $searchCriteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteria::class) ->disableOriginalConstructor() ->getMock(); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn($filterGroups); - $collection = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection::class) ->disableOriginalConstructor() ->getMock(); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->withAnyParameters(); - + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $this->searchResultFactoryMock->expects($this->once()) ->method('create') ->willReturn($collection); 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 76509010d70..48b99d5c55d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ItemRepositoryTest.php @@ -42,6 +42,11 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $extensionFactory; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * @var array */ @@ -72,6 +77,14 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); + $this->extensionFactory = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductOptionExtensionFactory::class) ->setMethods([ 'create', @@ -91,7 +104,9 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase $this->metadata, $this->searchResultFactory, $this->productOptionFactory, - $this->extensionFactory + $this->extensionFactory, + [], + $this->collectionProcessor ); $model->get(null); @@ -125,7 +140,9 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase $this->metadata, $this->searchResultFactory, $this->productOptionFactory, - $this->extensionFactory + $this->extensionFactory, + [], + $this->collectionProcessor ); $model->get($orderItemId); @@ -164,52 +181,17 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { $productType = 'configurable'; - $field = 'field'; - $value = 'value'; - $this->productOptionData = ['option1' => 'value1']; - - $filterMock = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filterMock->expects($this->once()) - ->method('getConditionType') - ->willReturn(null); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn($field); - $filterMock->expects($this->once()) - ->method('getValue') - ->willReturn($value); - - $filterGroupMock = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class) - ->disableOriginalConstructor() - ->getMock(); - $filterGroupMock->expects($this->once()) - ->method('getFilters') - ->willReturn([$filterMock]); - $searchCriteriaMock = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteria::class) ->disableOriginalConstructor() ->getMock(); - $searchCriteriaMock->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroupMock]); - $this->getProductOptionExtensionMock(); $productOption = $this->getProductOptionMock(); $orderItemMock = $this->getOrderMock($productType, $productOption); - $searchResultMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderItemSearchResultInterface::class) - ->setMethods([ - 'addFieldToFilter', - 'getItems', - ]) - ->getMockForAbstractClass(); - $searchResultMock->expects($this->once()) - ->method('addFieldToFilter') - ->with($field, ['eq' => $value]) - ->willReturnSelf(); + $searchResultMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Item\Collection::class) + ->disableOriginalConstructor() + ->getMock(); $searchResultMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); @@ -310,8 +292,9 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase $this->extensionFactory, [ $productType => $this->productOptionProcessorMock, - 'custom_options' => $this->productOptionProcessorMock, - ] + 'custom_options' => $this->productOptionProcessorMock + ], + $this->collectionProcessor ); return $model; } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/RepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/RepositoryTest.php index ab2f42acfd5..d5c893cbde9 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/RepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/RepositoryTest.php @@ -47,6 +47,11 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase */ protected $paymentResource; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * @var \Magento\Sales\Model\Order\Payment\Repository */ @@ -104,11 +109,19 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->repository = $objectManager->getObject( \Magento\Sales\Model\Order\Payment\Repository::class, [ 'searchResultFactory' => $this->searchResultFactory, 'metaData' => $this->metaData, + 'collectionProcessor' => $this->collectionProcessor, ] ); } @@ -173,9 +186,10 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $field = 'order_id'; - $value = 45; - $this->getListMock($field, $value); + $this->searchResultFactory->expects($this->atLeastOnce())->method('create')->willReturn($this->collection); + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($this->searchCriteria, $this->collection); $this->assertSame($this->collection, $this->repository->getList($this->searchCriteria)); } @@ -195,25 +209,4 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase return $payment; } - - /** - * @param $field - * @param $value - */ - protected function getListMock($field, $value) - { - $currentPage = 1; - $pageSize = 10; - $this->searchResultFactory->expects($this->atLeastOnce())->method('create')->willReturn($this->collection); - $this->searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$this->filterGroup]); - $this->filterGroup->expects($this->once())->method('getFilters')->willReturn([$this->filter]); - $this->filter->expects($this->once())->method('getConditionType')->willReturn(null); - $this->filter->expects($this->once())->method('getField')->willReturn($field); - $this->filter->expects($this->once())->method('getValue')->willReturn($value); - $this->collection->expects($this->once())->method('addFieldToFilter')->with($field, ['eq' => $value]); - $this->searchCriteria->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $this->searchCriteria->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $this->collection->expects($this->once())->method('setCurPage')->with(); - $this->collection->expects($this->once())->method('setPageSize')->with(); - } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php index 6526b4e729b..4ee404b064f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php @@ -74,6 +74,11 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase */ protected $repository; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -166,6 +171,13 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase false ); $entityStorageFactory->expects($this->once())->method('create')->willReturn($this->entityStorage); + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->repository = $objectManager->getObject( \Magento\Sales\Model\Order\Payment\Transaction\Repository::class, [ @@ -175,6 +187,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase 'sortOrderBuilder' => $this->sortOrderBuilder, 'metaData' => $this->metaData, 'entityStorageFactory' => $entityStorageFactory, + 'collectionProcessor' => $this->collectionProcessor ] ); } @@ -265,9 +278,10 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $field = 'txn_id'; - $value = '33-refund'; - $this->getListMock($field, $value); + $this->initListMock(); + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($this->searchCriteria, $this->collection); $this->assertSame($this->collection, $this->repository->getList($this->searchCriteria)); } @@ -389,7 +403,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase $this->searchCriteriaBuilder->expects($this->once()) ->method('create') ->willReturn($this->searchCriteria); - $this->getListMock(\Magento\Sales\Api\Data\TransactionInterface::TXN_TYPE, $transactionType); + $this->initListMock(); $transaction = $this->mockTransaction(1, true); $this->collection->expects($this->once())->method('getItems')->willReturn([$transaction]); $this->entityStorage->expects($this->once()) @@ -439,24 +453,11 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase } /** - * @param $field - * @param $value + * @return void */ - protected function getListMock($field, $value) + protected function initListMock() { - $currentPage = 1; - $pageSize = 10; $this->searchResultFactory->method('create')->willReturn($this->collection); - $this->searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$this->filterGroup]); - $this->filterGroup->expects($this->once())->method('getFilters')->willReturn([$this->filter]); - $this->filter->expects($this->once())->method('getConditionType')->willReturn(null); - $this->filter->expects($this->once())->method('getField')->willReturn($field); - $this->filter->expects($this->once())->method('getValue')->willReturn($value); - $this->collection->expects($this->once())->method('addFieldToFilter')->with($field, ['eq' => $value]); - $this->searchCriteria->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $this->searchCriteria->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $this->collection->expects($this->once())->method('setCurPage')->with(); - $this->collection->expects($this->once())->method('setPageSize')->with(); $this->collection->expects($this->once())->method('addPaymentInformation')->with(['method']); $this->collection->expects($this->once())->method('addOrderInformation')->with(['increment_id']); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentRepositoryTest.php index 3f213e899a6..4b87dcbd69a 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentRepositoryTest.php @@ -32,6 +32,11 @@ class ShipmentRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $searchResultFactory; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $objectManager = new ObjectManager($this); @@ -51,12 +56,19 @@ class ShipmentRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->subject = $objectManager->getObject( \Magento\Sales\Model\Order\ShipmentRepository::class, [ 'metadata' => $this->metadata, - 'searchResultFactory' => $this->searchResultFactory + 'searchResultFactory' => $this->searchResultFactory, + 'collectionProcessor' => $this->collectionProcessor ] ); } @@ -131,56 +143,24 @@ class ShipmentRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $filter = $this->getMock( - \Magento\Framework\Api\Filter::class, - ['getConditionType', 'getField', 'getValue'], - [], - '', - false - ); - $filter->expects($this->any()) - ->method('getConditionType') - ->willReturn(false); - $filter->expects($this->any()) - ->method('getField') - ->willReturn('test_field'); - $filter->expects($this->any()) - ->method('getValue') - ->willReturn('test_value'); - - $filterGroup = $this->getMock( - \Magento\Framework\Api\Search\FilterGroup::class, - ['getFilters'], - [], - '', - false - ); - $filterGroup->expects($this->once()) - ->method('getFilters') - ->willReturn([$filter]); - $searchCriteria = $this->getMock( \Magento\Framework\Api\SearchCriteria::class, - ['getFilterGroups'], + [], [], '', false ); - $searchCriteria->expects($this->once()) - ->method('getFilterGroups') - ->willReturn([$filterGroup]); $collection = $this->getMock( \Magento\Sales\Model\ResourceModel\Order\Shipment\Collection::class, - ['addFieldToFilter'], + [], [], '', false ); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->withAnyParameters(); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); $this->searchResultFactory->expects($this->once()) ->method('create') ->willReturn($collection); diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php index 67d7fa8852a..5535ac85095 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php @@ -39,6 +39,11 @@ class OrderRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $objectManager; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * Setup the test */ @@ -51,12 +56,19 @@ class OrderRepositoryTest extends \PHPUnit_Framework_TestCase $className = \Magento\Sales\Api\Data\OrderSearchResultInterfaceFactory::class; $this->searchResultFactory = $this->getMock($className, ['create'], [], '', false); - + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->model = $this->objectManager->getObject( \Magento\Sales\Model\OrderRepository::class, [ 'metadata' => $this->metadata, 'searchResultFactory' => $this->searchResultFactory, + 'collectionProcessor' => $this->collectionProcessor ] ); } @@ -67,12 +79,8 @@ class OrderRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetList() { - $fieldName = 'field'; $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); $collectionMock = $this->getMock(\Magento\Sales\Model\ResourceModel\Order\Collection::class, [], [], '', false); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filterGroupFilterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $sortOrderMock = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); $itemsMock = $this->getMockBuilder(OrderInterface::class)->disableOriginalConstructor()->getMock(); $extensionAttributes = $this->getMock( @@ -89,29 +97,15 @@ class OrderRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $itemsMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes); $extensionAttributes->expects($this->any()) ->method('getShippingAssignments') ->willReturn($shippingAssignmentBuilder); $this->searchResultFactory->expects($this->once())->method('create')->willReturn($collectionMock); - - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]); - $filterGroupMock->expects($this->once())->method('getFilters')->willReturn([$filterGroupFilterMock]); - $filterGroupFilterMock->expects($this->exactly(2))->method('getConditionType')->willReturn('eq'); - $filterGroupFilterMock->expects($this->atLeastOnce())->method('getField')->willReturn($fieldName); - $filterGroupFilterMock->expects($this->once())->method('getValue')->willReturn('value'); - $sortOrderMock->expects($this->once())->method('getDirection'); - $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]); - $sortOrderMock->expects($this->atLeastOnce())->method('getField')->willReturn($fieldName); - $collectionMock->expects($this->once())->method('addFieldToFilter') - ->willReturn(SortOrder::SORT_ASC); - $collectionMock->expects($this->once())->method('addOrder')->with($fieldName, 'DESC'); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn(4); - $collectionMock->expects($this->once())->method('setCurPage')->with(4); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn(42); - $collectionMock->expects($this->once())->method('setPageSize')->with(42); $collectionMock->expects($this->once())->method('getItems')->willReturn([$itemsMock]); $this->assertEquals($collectionMock, $this->model->getList($searchCriteriaMock)); diff --git a/app/code/Magento/SalesRule/Model/CouponRepository.php b/app/code/Magento/SalesRule/Model/CouponRepository.php index c9b2fdfb868..ad9b43f90e1 100644 --- a/app/code/Magento/SalesRule/Model/CouponRepository.php +++ b/app/code/Magento/SalesRule/Model/CouponRepository.php @@ -7,6 +7,7 @@ namespace Magento\SalesRule\Model; use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SortOrder; use Magento\SalesRule\Model\ResourceModel\Coupon\Collection; @@ -47,13 +48,18 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa */ protected $extensionAttributesJoinProcessor; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** + * CouponRepository constructor. * @param CouponFactory $couponFactory * @param RuleFactory $ruleFactory * @param \Magento\SalesRule\Api\Data\CouponSearchResultInterfaceFactory $searchResultFactory - * @param \Magento\SalesRule\Model\ResourceModel\Coupon\CollectionFactory $collectionFactory + * @param ResourceModel\Coupon\CollectionFactory $collectionFactory * @param Spi\CouponResourceInterface $resourceModel * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param CollectionProcessorInterface|null $collectionProcessor */ public function __construct( \Magento\SalesRule\Model\CouponFactory $couponFactory, @@ -61,7 +67,8 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa \Magento\SalesRule\Api\Data\CouponSearchResultInterfaceFactory $searchResultFactory, \Magento\SalesRule\Model\ResourceModel\Coupon\CollectionFactory $collectionFactory, \Magento\SalesRule\Model\Spi\CouponResourceInterface $resourceModel, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->couponFactory = $couponFactory; $this->ruleFactory = $ruleFactory; @@ -69,6 +76,7 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa $this->collectionFactory = $collectionFactory; $this->resourceModel = $resourceModel; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -154,27 +162,7 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa $couponInterfaceName = \Magento\SalesRule\Api\Data\CouponInterface::class; $this->extensionAttributesJoinProcessor->process($collection, $couponInterfaceName); - //Add filters from root filter group to the collection - /** @var FilterGroup $group */ - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders === null) { - $sortOrders = []; - } - /** @var \Magento\Framework\Api\SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $field = $sortOrder->getField(); - $collection->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); - + $this->collectionProcessor->process($searchCriteria, $collection); $coupons = []; /** @var \Magento\SalesRule\Model\Coupon $couponModel */ foreach ($collection->getItems() as $couponModel) { @@ -215,6 +203,7 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa * * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup * @param Collection $collection + * @deprecated * @return void */ protected function addFilterGroupToCollection( @@ -232,4 +221,20 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa $collection->addFieldToFilter($fields, $conditions); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/SalesRule/Model/RuleRepository.php b/app/code/Magento/SalesRule/Model/RuleRepository.php index e26d7ad144f..2d875e9ede0 100644 --- a/app/code/Magento/SalesRule/Model/RuleRepository.php +++ b/app/code/Magento/SalesRule/Model/RuleRepository.php @@ -6,6 +6,7 @@ namespace Magento\SalesRule\Model; use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SortOrder; use Magento\SalesRule\Model\ResourceModel\Rule\Collection; @@ -62,16 +63,22 @@ class RuleRepository implements \Magento\SalesRule\Api\RuleRepositoryInterface */ protected $ruleCollectionFactory; + /** @var CollectionProcessorInterface */ + private $collectionProcessor; + /** - * @param \Magento\SalesRule\Model\RuleFactory $ruleFactory + * RuleRepository constructor. + * @param RuleFactory $ruleFactory * @param \Magento\SalesRule\Api\Data\RuleInterfaceFactory $ruleDataFactory * @param \Magento\SalesRule\Api\Data\ConditionInterfaceFactory $conditionDataFactory - * @param \Magento\SalesRule\Model\Converter\ToDataModel $toDataModelConverter - * @param \Magento\SalesRule\Model\Converter\ToModel $toModelConverter + * @param Converter\ToDataModel $toDataModelConverter + * @param Converter\ToModel $toModelConverter * @param \Magento\SalesRule\Api\Data\RuleSearchResultInterfaceFactory $searchResultFactory * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor - * @param \Magento\SalesRule\Model\ResourceModel\Rule\CollectionFactory $ruleCollectionFactory + * @param ResourceModel\Rule\CollectionFactory $ruleCollectionFactory * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor + * @param CollectionProcessorInterface|null $collectionProcessor + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\SalesRule\Model\RuleFactory $ruleFactory, @@ -82,7 +89,8 @@ class RuleRepository implements \Magento\SalesRule\Api\RuleRepositoryInterface \Magento\SalesRule\Api\Data\RuleSearchResultInterfaceFactory $searchResultFactory, \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, \Magento\SalesRule\Model\ResourceModel\Rule\CollectionFactory $ruleCollectionFactory, - \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor + \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->ruleFactory = $ruleFactory; $this->ruleDataFactory = $ruleDataFactory; @@ -93,6 +101,7 @@ class RuleRepository implements \Magento\SalesRule\Api\RuleRepositoryInterface $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; $this->ruleCollectionFactory = $ruleCollectionFactory; $this->dataObjectProcessor = $dataObjectProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -134,28 +143,7 @@ class RuleRepository implements \Magento\SalesRule\Api\RuleRepositoryInterface $ruleInterfaceName = \Magento\SalesRule\Api\Data\RuleInterface::class; $this->extensionAttributesJoinProcessor->process($collection, $ruleInterfaceName); - //Add filters from root filter group to the collection - /** @var FilterGroup $group */ - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders === null) { - $sortOrders = []; - } - /** @var \Magento\Framework\Api\SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $field = $sortOrder->getField(); - $collection->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); - $collection->load(); - + $this->collectionProcessor->process($searchCriteria, $collection); $rules = []; /** @var \Magento\SalesRule\Model\Rule $ruleModel */ foreach ($collection->getItems() as $ruleModel) { @@ -195,6 +183,7 @@ class RuleRepository implements \Magento\SalesRule\Api\RuleRepositoryInterface * * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup * @param Collection $collection + * @deprecated * @return void */ protected function addFilterGroupToCollection( @@ -212,4 +201,20 @@ class RuleRepository implements \Magento\SalesRule\Api\RuleRepositoryInterface $collection->addFieldToFilter($fields, $conditions); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php index 1257b100b21..19dfc5e21c8 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php @@ -57,6 +57,11 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $objectManager; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -92,6 +97,14 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase false ); + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); + $this->model = $this->objectManager->getObject( \Magento\SalesRule\Model\CouponRepository::class, [ @@ -100,7 +113,8 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase 'searchResultFactory' => $this->searchResultFactory, 'collectionFactory' => $this->collectionFactory, 'resourceModel' => $this->resource, - 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock + 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, + 'collectionProcessor' => $this->collectionProcessor, ] ); } @@ -219,9 +233,6 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { $collectionSize = 1; - $currentPage = 42; - $pageSize = 4; - /** * @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteriaMock */ @@ -233,35 +244,16 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $sortOrderMock = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); - $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') ->with($collectionMock, \Magento\SalesRule\Api\Data\CouponInterface::class); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $this->searchResultsMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock); $this->collectionFactory->expects($this->once())->method('create')->willReturn($collectionMock); - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]); - $filterGroupMock->expects($this->once())->method('getFilters')->willReturn([$filterMock]); - $filterMock->expects($this->exactly(2))->method('getConditionType')->willReturn('eq'); - $filterMock->expects($this->once())->method('getField')->willReturn( - 'coupon_id' - ); - $filterMock->expects($this->once())->method('getValue')->willReturn('value'); - $collectionMock->expects($this->once())->method('addFieldToFilter') - ->with([0 => 'coupon_id'], [0 => ['eq' => 'value']]); $collectionMock->expects($this->once())->method('getSize')->willReturn($collectionSize); $this->searchResultsMock->expects($this->once())->method('setTotalCount')->with($collectionSize); - $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]); - $sortOrderMock->expects($this->once())->method('getField')->willReturn('sort_order'); - $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC); - $collectionMock->expects($this->once())->method('addOrder')->with('sort_order', 'ASC'); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); $collectionMock->expects($this->once())->method('getItems')->willReturn([]); $this->searchResultsMock->expects($this->once())->method('setItems')->with([]); $this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultsMock); diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/RuleRepositoryTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/RuleRepositoryTest.php index 7412f8b05f8..4b309442c55 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/RuleRepositoryTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/RuleRepositoryTest.php @@ -54,6 +54,11 @@ class RuleRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $toModelConverter; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $this->ruleFactory = $this->getMock(\Magento\SalesRule\Model\RuleFactory::class, ['create'], [], '', false); @@ -77,6 +82,13 @@ class RuleRepositoryTest extends \PHPUnit_Framework_TestCase $this->extensionAttributesJoinProcessorMock = $this->getMock($className, ['process'], [], '', false); $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->collectionProcessor = $this->getMock( + \Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface::class, + [], + [], + '', + false + ); $this->ruleRepository = $objectManager->getObject( \Magento\SalesRule\Model\RuleRepository::class, [ @@ -85,7 +97,8 @@ class RuleRepositoryTest extends \PHPUnit_Framework_TestCase 'toModelConverter' => $this->toModelConverter, 'searchResultFactory' => $this->searchResultFactory, 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, - 'ruleCollectionFactory' => $this->collectionFactory + 'ruleCollectionFactory' => $this->collectionFactory, + 'collectionProcessor' => $this->collectionProcessor ] ); } @@ -134,9 +147,6 @@ class RuleRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { $collectionSize = 1; - $currentPage = 42; - $pageSize = 4; - /** * @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteriaMock */ @@ -148,9 +158,6 @@ class RuleRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $sortOrderMock = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') @@ -158,25 +165,11 @@ class RuleRepositoryTest extends \PHPUnit_Framework_TestCase $this->searchResultsMock->expects($this->once())->method('setSearchCriteria')->with($searchCriteriaMock); $this->collectionFactory->expects($this->once())->method('create')->willReturn($collectionMock); - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]); - $filterGroupMock->expects($this->once())->method('getFilters')->willReturn([$filterMock]); - $filterMock->expects($this->exactly(2))->method('getConditionType')->willReturn('eq'); - $filterMock->expects($this->once())->method('getField')->willReturn( - 'rule_id' - ); - $filterMock->expects($this->once())->method('getValue')->willReturn('value'); - $collectionMock->expects($this->once())->method('addFieldToFilter') - ->with([0 => 'rule_id'], [0 => ['eq' => 'value']]); $collectionMock->expects($this->once())->method('getSize')->willReturn($collectionSize); $this->searchResultsMock->expects($this->once())->method('setTotalCount')->with($collectionSize); - $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]); - $sortOrderMock->expects($this->once())->method('getField')->willReturn('sort_order'); - $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC); - $collectionMock->expects($this->once())->method('addOrder')->with('sort_order', 'ASC'); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $collectionMock->expects($this->once())->method('setPageSize')->with($pageSize); + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock); $collectionMock->expects($this->once())->method('getItems')->willReturn([]); $this->searchResultsMock->expects($this->once())->method('setItems')->with([]); $this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultsMock); diff --git a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php index 59d79a7fc27..dd0644dc46d 100644 --- a/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php +++ b/app/code/Magento/Vault/Test/Unit/Model/PaymentTokenRepositoryTest.php @@ -170,10 +170,11 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase $this->searchResultsFactoryMock->expects($this->once()) ->method('create') ->willReturn($this->searchResults); - + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($this->searchCriteriaMock, $this->collectionMock); $list = $this->repositoryModel->getList($this->searchCriteriaMock); $this->assertSame($this->searchResults, $list); - $this->assertSame( $this->paymentTokenMock, $list->getItems()[0] diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php index fdf72821de0..6c2a6567db8 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Service\V1; +use Magento\Framework\Api\SortOrderBuilder; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -44,10 +45,14 @@ class CreditmemoListTest extends WebapiAbstract /** * Test creditmemo list service * - * @magentoApiDataFixture Magento/Sales/_files/creditmemo_with_list.php + * @magentoApiDataFixture Magento/Sales/_files/creditmemo_list.php */ public function testCreditmemoList() { + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->get( + SortOrderBuilder::class + ); /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ $searchCriteriaBuilder = $this->objectManager->create( \Magento\Framework\Api\SearchCriteriaBuilder::class @@ -57,16 +62,29 @@ class CreditmemoListTest extends WebapiAbstract $filterBuilder = $this->objectManager->create( \Magento\Framework\Api\FilterBuilder::class ); + $stateFilter = $filterBuilder + ->setField('state') + ->setValue((string)\Magento\Sales\Model\Order\Creditmemo::STATE_OPEN) + ->setConditionType('eq') + ->create(); + $incrementFilter = $filterBuilder + ->setField('increment_id') + ->setValue('456') + ->setConditionType('eq') + ->create(); + $zeroStatusFilter = $filterBuilder + ->setField('creditmemo_status') + ->setValue('0') + ->setConditionType('eq') + ->create(); + $sortOrder = $sortOrderBuilder + ->setField('grand_total') + ->setDirection('ASC') + ->create(); + $searchCriteriaBuilder->addFilters([$stateFilter]); + $searchCriteriaBuilder->addFilters([$incrementFilter, $zeroStatusFilter]); + $searchCriteriaBuilder->addSortOrder($sortOrder); - $searchCriteriaBuilder->addFilters( - [ - $filterBuilder - ->setField('state') - ->setValue((string)\Magento\Sales\Model\Order\Creditmemo::STATE_OPEN) - ->setConditionType('eq') - ->create(), - ] - ); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -85,8 +103,10 @@ class CreditmemoListTest extends WebapiAbstract $result = $this->_webApiCall($serviceInfo, $requestData); // TODO Test fails, due to the inability of the framework API to handle data collection $this->assertArrayHasKey('items', $result); - $this->assertCount(1, $result['items']); + $this->assertCount(2, $result['items']); $this->assertArrayHasKey('search_criteria', $result); + $this->assertEquals('789', $result['items'][0]['increment_id']); + $this->assertEquals('456', $result['items'][1]['increment_id']); $this->assertEquals($searchData, $result['search_criteria']); } } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php index 3624029740f..f9e6006ebe2 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Service\V1; +use Magento\Framework\Api\SortOrderBuilder; use Magento\TestFramework\TestCase\WebapiAbstract; /** @@ -29,10 +30,14 @@ class InvoiceListTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/Sales/_files/invoice.php + * @magentoApiDataFixture Magento/Sales/_files/invoice_list.php */ public function testInvoiceList() { + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->get( + SortOrderBuilder::class + ); /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ $searchCriteriaBuilder = $this->objectManager->create( \Magento\Framework\Api\SearchCriteriaBuilder::class @@ -43,15 +48,29 @@ class InvoiceListTest extends WebapiAbstract \Magento\Framework\Api\FilterBuilder::class ); - $searchCriteriaBuilder->addFilters( - [ - $filterBuilder - ->setField('state') - ->setValue((string)\Magento\Sales\Model\Order\Invoice::STATE_PAID) - ->setConditionType('eq') - ->create(), - ] - ); + $stateFilter = $filterBuilder + ->setField('state') + ->setValue((string)\Magento\Sales\Model\Order\Creditmemo::STATE_OPEN) + ->setConditionType('eq') + ->create(); + $incrementFilter = $filterBuilder + ->setField('increment_id') + ->setValue('456') + ->setConditionType('eq') + ->create(); + $zeroStatusFilter = $filterBuilder + ->setField('can_void_flag') + ->setValue('0') + ->setConditionType('eq') + ->create(); + $sortOrder = $sortOrderBuilder + ->setField('grand_total') + ->setDirection('ASC') + ->create(); + + $searchCriteriaBuilder->addFilters([$stateFilter]); + $searchCriteriaBuilder->addFilters([$incrementFilter, $zeroStatusFilter]); + $searchCriteriaBuilder->addSortOrder($sortOrder); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -70,8 +89,10 @@ class InvoiceListTest extends WebapiAbstract $result = $this->_webApiCall($serviceInfo, $requestData); // TODO Test fails, due to the inability of the framework API to handle data collection $this->assertArrayHasKey('items', $result); - $this->assertCount(1, $result['items']); + $this->assertCount(2, $result['items']); $this->assertArrayHasKey('search_criteria', $result); + $this->assertEquals('789', $result['items'][0]['increment_id']); + $this->assertEquals('456', $result['items'][1]['increment_id']); $this->assertEquals($searchData, $result['search_criteria']); } } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderItemGetListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderItemGetListTest.php index 25af17f6bb1..08b7ecfa979 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderItemGetListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderItemGetListTest.php @@ -27,26 +27,40 @@ class OrderItemGetListTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/Sales/_files/order.php + * @magentoApiDataFixture Magento/Sales/_files/order_item_list.php */ public function testGetList() { + $expectedRowTotals = [112, 102, 92]; + /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); /** @var \Magento\Sales\Model\Order $order */ $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); $order->loadByIncrementId(self::ORDER_INCREMENT_ID); - /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ $searchCriteriaBuilder = $this->objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); /** @var $filterBuilder \Magento\Framework\Api\FilterBuilder */ $filterBuilder = $this->objectManager->create(\Magento\Framework\Api\FilterBuilder::class); - $searchCriteriaBuilder->addFilters( - [ - $filterBuilder->setField('order_id') - ->setValue($order->getId()) - ->create(), - ] - ); + $filter2 = $filterBuilder->setField('product_type') + ->setValue('configurable') + ->create(); + $filter3 = $filterBuilder->setField('base_price') + ->setValue(110) + ->setConditionType('gteq') + ->create(); + $filter4 = $filterBuilder->setField('product_type') + ->setValue('simple') + ->setConditionType('neq') + ->create(); + $sortOrder = $sortOrderBuilder->setField('row_total') + ->setDirection('DESC') + ->create(); + $searchCriteriaBuilder->addFilters([$filter4]); + $searchCriteriaBuilder->addFilters([$filter2, $filter3]); + $searchCriteriaBuilder->addSortOrder($sortOrder); $requestData = ['searchCriteria' => $searchCriteriaBuilder->create()->__toArray()]; @@ -66,9 +80,15 @@ class OrderItemGetListTest extends WebapiAbstract $this->assertTrue(is_array($response)); $this->assertArrayHasKey('items', $response); - $this->assertCount(1, $response['items']); + $this->assertCount(3, $response['items']); $this->assertTrue(is_array($response['items'][0])); - $this->assertOrderItem(current($order->getItems()), $response['items'][0]); + $rowTotals = []; + + foreach ($response['items'] as $item) { + $rowTotals[] = $item['row_total']; + } + + $this->assertEquals($expectedRowTotals, $rowTotals); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php index 13a7de42019..85cc726ef69 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php @@ -30,10 +30,14 @@ class OrderListTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/Sales/_files/order.php + * @magentoApiDataFixture Magento/Sales/_files/order_list.php */ public function testOrderList() { + /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ $searchCriteriaBuilder = $this->objectManager->create( \Magento\Framework\Api\SearchCriteriaBuilder::class @@ -43,16 +47,27 @@ class OrderListTest extends WebapiAbstract $filterBuilder = $this->objectManager->create( \Magento\Framework\Api\FilterBuilder::class ); - - $searchCriteriaBuilder->addFilters( - [ - $filterBuilder - ->setField('status') - ->setValue('processing') - ->setConditionType('eq') - ->create(), - ] - ); + $filter1 = $filterBuilder + ->setField('status') + ->setValue('processing') + ->setConditionType('eq') + ->create(); + $filter2 = $filterBuilder + ->setField('state') + ->setValue(\Magento\Sales\Model\Order::STATE_NEW) + ->setConditionType('eq') + ->create(); + $filter3 = $filterBuilder + ->setField('increment_id') + ->setValue('100000001') + ->setConditionType('eq') + ->create(); + $sortOrder = $sortOrderBuilder->setField('grand_total') + ->setDirection('DESC') + ->create(); + $searchCriteriaBuilder->addFilters([$filter1]); + $searchCriteriaBuilder->addFilters([$filter2, $filter3]); + $searchCriteriaBuilder->addSortOrder($sortOrder); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -70,8 +85,10 @@ class OrderListTest extends WebapiAbstract $result = $this->_webApiCall($serviceInfo, $requestData); $this->assertArrayHasKey('items', $result); - $this->assertCount(1, $result['items']); + $this->assertCount(2, $result['items']); $this->assertArrayHasKey('search_criteria', $result); $this->assertEquals($searchData, $result['search_criteria']); + $this->assertEquals('100000002', $result['items'][0]['increment_id']); + $this->assertEquals('100000001', $result['items'][1]['increment_id']); } } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php index 3dd721b3b88..3d00dd79485 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php @@ -29,10 +29,14 @@ class ShipmentListTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/Sales/_files/shipment.php + * @magentoApiDataFixture Magento/Sales/_files/shipment_list.php */ public function testShipmentList() { + /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ $searchCriteriaBuilder = $this->objectManager->create( \Magento\Framework\Api\SearchCriteriaBuilder::class @@ -42,16 +46,28 @@ class ShipmentListTest extends WebapiAbstract $filterBuilder = $this->objectManager->create( \Magento\Framework\Api\FilterBuilder::class ); + $filter1 = $filterBuilder + ->setField('shipment_status') + ->setValue(1) + ->setConditionType('eq') + ->create(); + $filter2 = $filterBuilder + ->setField('store_id') + ->setValue(1) + ->setConditionType('eq') + ->create(); + $filter3 = $filterBuilder + ->setField('shipping_address_id') + ->setValue(3) + ->setConditionType('eq') + ->create(); + $sortOrder = $sortOrderBuilder->setField('increment_id') + ->setDirection('ASC') + ->create(); + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3]); + $searchCriteriaBuilder->addSortOrder($sortOrder); - $searchCriteriaBuilder->addFilters( - [ - $filterBuilder - ->setField('shipment_status') - ->setValue((string)\Magento\Sales\Model\Order\Shipment::STATUS_NEW) - ->setConditionType('eq') - ->create() - ] - ); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -70,8 +86,10 @@ class ShipmentListTest extends WebapiAbstract $result = $this->_webApiCall($serviceInfo, $requestData); // TODO Test fails, due to the inability of the framework API to handle data collection $this->assertArrayHasKey('items', $result); - $this->assertCount(1, $result['items']); + $this->assertCount(2, $result['items']); $this->assertArrayHasKey('search_criteria', $result); $this->assertEquals($searchData, $result['search_criteria']); + $this->assertEquals('100000002', $result['items'][0]['increment_id']); + $this->assertEquals('100000003', $result['items'][1]['increment_id']); } } diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php index d546bdd01ad..3a2aab87946 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php @@ -88,9 +88,9 @@ class TransactionTest extends WebapiAbstract /** * Tests list of order transactions - * @dataProvider filtersDataProvider + * @magentoApiDataFixture Magento/Sales/_files/transactions_list.php */ - public function testTransactionList($filters) + public function testTransactionList() { /** @var Order $order */ $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); @@ -114,8 +114,38 @@ class TransactionTest extends WebapiAbstract $searchCriteriaBuilder = $this->objectManager->create( \Magento\Framework\Api\SearchCriteriaBuilder::class ); + /** @var $filterBuilder \Magento\Framework\Api\FilterBuilder */ + $filterBuilder = $this->objectManager->create( + \Magento\Framework\Api\FilterBuilder::class + ); + /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->create( + \Magento\Framework\Api\SortOrderBuilder::class + ); + $filter1 = $filterBuilder->setField('txn_id') + ->setValue('%trx_auth%') + ->setConditionType('like') + ->create(); + $filter2 = $filterBuilder->setField('txn_id') + ->setValue('trx_capture') + ->setConditionType('eq') + ->create(); + $filter3 = $filterBuilder->setField('parent_txn_id') + ->setValue(null) + ->setConditionType('null') + ->create(); + $filter4 = $filterBuilder->setField('is_closed') + ->setValue(0) + ->setConditionType('eq') + ->create(); + $sortOrder = $sortOrderBuilder->setField('parent_id') + ->setDirection('ASC') + ->create(); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3, $filter4]); + $searchCriteriaBuilder->addSortOrder($sortOrder); - $searchCriteriaBuilder->addFilters($filters); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -132,14 +162,12 @@ class TransactionTest extends WebapiAbstract ], ]; $result = $this->_webApiCall($serviceInfo, $requestData); - $this->assertArrayHasKey('items', $result); $transactionData = $this->getPreparedTransactionData($transaction); $childTransactionData = $this->getPreparedTransactionData($childTransaction); $transactionData['child_transactions'][] = $childTransactionData; $expectedData = [$transactionData, $childTransactionData]; - $this->assertEquals($expectedData, $result['items']); $this->assertArrayHasKey('search_criteria', $result); $this->assertEquals($searchData, $result['search_criteria']); @@ -168,7 +196,7 @@ class TransactionTest extends WebapiAbstract 'order_id' => (int)$transaction->getOrderId(), 'payment_id' => (int)$transaction->getPaymentId(), 'txn_id' => $transaction->getTxnId(), - 'parent_txn_id' => ($transaction->getParentTxnId() ? (string)$transaction->getParentTxnId() : ''), + 'parent_txn_id' => ($transaction->getParentTxnId() ? (string)$transaction->getParentTxnId() : null), 'txn_type' => $transaction->getTxnType(), 'is_closed' => (int)$transaction->getIsClosed(), 'additional_information' => ['data'], @@ -181,6 +209,7 @@ class TransactionTest extends WebapiAbstract } /** + * @deprecated * @return array */ public function filtersDataProvider() diff --git a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php index 8e4fc715a2d..832beb9779f 100644 --- a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php @@ -15,6 +15,16 @@ class CouponRepositoryTest extends WebapiAbstract const RESOURCE_PATH = '/V1/coupons'; const SERVICE_VERSION = "V1"; + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + protected function getCouponData() { $data = [ @@ -88,6 +98,66 @@ class CouponRepositoryTest extends WebapiAbstract return $result; } + /** + * @magentoApiDataFixture Magento/SalesRule/_files/coupons.php + */ + public function testGetListWithMultipleFiltersAndSorting() + { + /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ + $searchCriteriaBuilder = $this->objectManager->create( + \Magento\Framework\Api\SearchCriteriaBuilder::class + ); + /** @var $filterBuilder \Magento\Framework\Api\FilterBuilder */ + $filterBuilder = $this->objectManager->create( + \Magento\Framework\Api\FilterBuilder::class + ); + /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->create( + \Magento\Framework\Api\SortOrderBuilder::class + ); + + $filter1 = $filterBuilder->setField('type') + ->setValue(1) + ->setConditionType('eq') + ->create(); + $filter2 = $filterBuilder->setField('code') + ->setValue('coupon_code_auto') + ->setConditionType('eq') + ->create(); + $filter3 = $filterBuilder->setField('is_primary') + ->setValue(1) + ->setConditionType('eq') + ->create(); + $sortOrder = $sortOrderBuilder->setField('code') + ->setDirection('DESC') + ->create(); + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3]); + $searchCriteriaBuilder->addSortOrder($sortOrder); + $searchData = $searchCriteriaBuilder->create()->__toArray(); + $requestData = ['searchCriteria' => $searchData]; + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '/search' . '?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $result = $this->_webApiCall($serviceInfo, $requestData); + $this->assertArrayHasKey('items', $result); + $this->assertArrayHasKey('search_criteria', $result); + $this->assertCount(2, $result['items']); + $this->assertEquals('autogenerated_3_2', $result['items'][0]['code']); + $this->assertEquals('autogenerated_2_1', $result['items'][1]['code']); + $this->assertEquals($searchData, $result['search_criteria']); + } + public function verifyGetList($couponId) { $searchCriteria = [ diff --git a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php index 6dd9d7319a7..bc8da5e2d82 100644 --- a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php @@ -15,6 +15,16 @@ class RuleRepositoryTest extends WebapiAbstract const RESOURCE_PATH = '/V1/salesRules'; const SERVICE_VERSION = "V1"; + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + } + protected function getSalesRuleData() { $data = [ @@ -161,6 +171,68 @@ class RuleRepositoryTest extends WebapiAbstract return $response['items'][0]; } + /** + * @magentoApiDataFixture Magento/SalesRule/_files/rules.php + */ + public function testGetListWithMultipleFiltersAndSorting() + { + /** @var $searchCriteriaBuilder \Magento\Framework\Api\SearchCriteriaBuilder */ + $searchCriteriaBuilder = $this->objectManager->create( + \Magento\Framework\Api\SearchCriteriaBuilder::class + ); + /** @var $filterBuilder \Magento\Framework\Api\FilterBuilder */ + $filterBuilder = $this->objectManager->create( + \Magento\Framework\Api\FilterBuilder::class + ); + /** @var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = $this->objectManager->create( + \Magento\Framework\Api\SortOrderBuilder::class + ); + + $filter1 = $filterBuilder->setField('is_rss') + ->setValue(1) + ->setConditionType('eq') + ->create(); + $filter2 = $filterBuilder->setField('name') + ->setValue('#4') + ->setConditionType('eq') + ->create(); + $filter3 = $filterBuilder->setField('uses_per_coupon') + ->setValue(1) + ->setConditionType('gt') + ->create(); + $sortOrder = $sortOrderBuilder->setField('name') + ->setDirection('ASC') + ->create(); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3]); + $searchCriteriaBuilder->addSortOrder($sortOrder); + $searchData = $searchCriteriaBuilder->create()->__toArray(); + + $requestData = ['searchCriteria' => $searchData]; + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH . '/search?' . http_build_query($requestData), + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_NAME . 'GetList', + ], + ]; + + $result = $this->_webApiCall($serviceInfo, $requestData); + $this->assertArrayHasKey('items', $result); + $this->assertArrayHasKey('search_criteria', $result); + $this->assertCount(2, $result['items']); + $this->assertEquals('#1', $result['items'][0]['name']); + $this->assertEquals('#2', $result['items'][1]['name']); + $this->assertEquals($searchData, $result['search_criteria']); + } + /** * Create Sales rule * diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/AddressRepositoryTest.php new file mode 100644 index 00000000000..687fff317ca --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/AddressRepositoryTest.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; + +/** + * Class AddressRepositoryTest + * @package Magento\Sales\Model\Order] + * @magentoDbIsolation enabled + */ +class AddressRepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** @var AddressRepository */ + protected $repository; + + /** @var SortOrderBuilder */ + private $sortOrderBuilder; + + /** @var FilterBuilder */ + private $filterBuilder; + + /** @var SearchCriteriaBuilder */ + private $searchCriteriaBuilder; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->repository = $objectManager->create(AddressRepository::class); + $this->searchCriteriaBuilder = $objectManager->create( + \Magento\Framework\Api\SearchCriteriaBuilder::class + ); + $this->filterBuilder = $objectManager->get( + \Magento\Framework\Api\FilterBuilder::class + ); + $this->sortOrderBuilder = $objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); + } + + /** + * @magentoDataFixture Magento/Sales/_files/address_list.php + */ + public function testGetListWithMultipleFiltersAndSorting() + { + $filter1 = $this->filterBuilder + ->setField('postcode') + ->setConditionType('neq') + ->setValue('ZX0789A') + ->create(); + $filter2 = $this->filterBuilder + ->setField('address_type') + ->setValue('billing') + ->create(); + $filter3 = $this->filterBuilder + ->setField('city') + ->setValue('Ena4ka') + ->create(); + $sortOrder = $this->sortOrderBuilder + ->setField('region_id') + ->setDirection('DESC') + ->create(); + + $this->searchCriteriaBuilder->addFilters([$filter1]); + $this->searchCriteriaBuilder->addFilters([$filter2, $filter3]); + $this->searchCriteriaBuilder->addSortOrder($sortOrder); + $searchCriteria = $this->searchCriteriaBuilder->create(); + /** @var \Magento\Sales\Api\Data\OrderAddressSearchResultInterface $result */ + $result = $this->repository->getList($searchCriteria); + $items = $result->getItems(); + $this->assertCount(2, $items); + $this->assertEquals('ZX0789', array_shift($items)->getPostcode()); + $this->assertEquals('47676', array_shift($items)->getPostcode()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Payment/RepositoryTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Payment/RepositoryTest.php new file mode 100644 index 00000000000..9d82e364787 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Payment/RepositoryTest.php @@ -0,0 +1,80 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Payment; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; + +/** + * Class RepositoryTest + * @package Magento\Sales\Model\Order\Payment\ + * @magentoDbIsolation enabled + */ +class RepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** @var Repository */ + protected $repository; + + /** @var SortOrderBuilder */ + private $sortOrderBuilder; + + /** @var FilterBuilder */ + private $filterBuilder; + + /** @var SearchCriteriaBuilder */ + private $searchCriteriaBuilder; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->repository = $objectManager->create(Repository::class); + $this->searchCriteriaBuilder = $objectManager->create( + \Magento\Framework\Api\SearchCriteriaBuilder::class + ); + $this->filterBuilder = $objectManager->get( + \Magento\Framework\Api\FilterBuilder::class + ); + $this->sortOrderBuilder = $objectManager->get( + \Magento\Framework\Api\SortOrderBuilder::class + ); + } + + /** + * @magentoDataFixture Magento/Sales/_files/order_payment_list.php + */ + public function testGetListWithMultipleFiltersAndSorting() + { + $filter1 = $this->filterBuilder + ->setField('cc_ss_start_year') + ->setValue('2014') + ->create(); + $filter2 = $this->filterBuilder + ->setField('cc_exp_month') + ->setValue('09') + ->create(); + $filter3 = $this->filterBuilder + ->setField('method') + ->setValue('checkmo') + ->create(); + $sortOrder = $this->sortOrderBuilder + ->setField('cc_exp_month') + ->setDirection('DESC') + ->create(); + + $this->searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $this->searchCriteriaBuilder->addFilters([$filter3]); + $this->searchCriteriaBuilder->addSortOrder($sortOrder); + $searchCriteria = $this->searchCriteriaBuilder->create(); + /** @var \Magento\Sales\Api\Data\OrderPaymentSearchResultInterface $result */ + $result = $this->repository->getList($searchCriteria); + $items = $result->getItems(); + $this->assertCount(2, $items); + $this->assertEquals('456', array_shift($items)->getCcLast4()); + $this->assertEquals('123', array_shift($items)->getCcLast4()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/address_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/address_list.php new file mode 100644 index 00000000000..d48a97b8b3b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/address_list.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +$addresses = [ + [ + 'telephone' => 3234676, + 'postcode' => 47676, + 'country_id' => 'US', + 'city' => 'CityX', + 'street' => ['Black str, 48'], + 'lastname' => 'Smith', + 'firstname' => 'John', + 'address_type' => 'shipping', + 'email' => 'some_email@mail.com', + 'region_id' => 1, + ], + [ + 'telephone' => 3234676, + 'postcode' => '47676', + 'country_id' => 'US', + 'city' => 'CityX', + 'street' => ['Black str, 48'], + 'lastname' => 'Smith', + 'firstname' => 'John', + 'address_type' => 'billing', + 'email' => 'some_email@mail.com', + 'region_id' => 1, + ], + [ + 'telephone' => 123123, + 'postcode' => 'ZX0789', + 'country_id' => 'US', + 'city' => 'Ena4ka', + 'street' => ['Black', 'White'], + 'lastname' => 'Doe', + 'firstname' => 'John', + 'address_type' => 'billing', + 'email' => 'some_email@mail.com', + 'region_id' => 2, + ], + [ + 'telephone' => 123123, + 'postcode' => 'ZX0789A', + 'country_id' => 'US', + 'city' => 'Ena4ka', + 'street' => ['Black', 'White'], + 'lastname' => 'Doe', + 'firstname' => 'John', + 'address_type' => 'shipping', + 'email' => 'some_email@mail.com', + 'region_id' => 1, + ] +]; + +/** @var array $addresses */ +foreach ($addresses as $addressData) { + /** @var $address \Magento\Sales\Model\Order\Address */ + $address = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Address::class + ); + $address + ->setData($addressData) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/address_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/address_list_rollback.php new file mode 100644 index 00000000000..248f6469ad8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/address_list_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list.php new file mode 100644 index 00000000000..08b7ebbaa65 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; + +require 'order.php'; +/** @var Order $order */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$creditMemos = [ + [ + 'store_id' => 1, + 'grand_total' => 280.00, + 'order_id' => $order->getId(), + 'email_sent' => 0, + 'send_email' => 0, + 'increment_id' => '123', + 'creditmemo_status' => 1, + 'state' => 1 + ], + [ + 'store_id' => 1, + 'grand_total' => 450.00, + 'order_id' => $order->getId(), + 'email_sent' => 1, + 'send_email' => 1, + 'increment_id' => '456', + 'creditmemo_status' => 1, + 'state' => 1 + ], + [ + 'store_id' => 1, + 'grand_total' => 10.00, + 'order_id' => $order->getId(), + 'email_sent' => 1, + 'send_email' => 1, + 'increment_id' => '789', + 'creditmemo_status' => 0, + 'state' => 1 + ], + [ + 'store_id' => 1, + 'grand_total' => 1110.00, + 'order_id' => $order->getId(), + 'email_sent' => 1, + 'increment_id' => '012', + 'send_email' => 1, + 'creditmemo_status' => 1, + 'state' => 0 + ], +]; + +/** @var array $creditMemoData */ +foreach ($creditMemos as $creditMemoData) { + /** @var \Magento\Sales\Model\Order\Creditmemo $creditMemo */ + $creditMemo = $objectManager->create(\Magento\Sales\Model\Order\Creditmemo::class); + $creditMemo + ->setData($creditMemoData) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list_rollback.php new file mode 100644 index 00000000000..248f6469ad8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_list_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php new file mode 100644 index 00000000000..41ed4fc2206 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; + +require 'order.php'; +/** @var Order $order */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +$invoices = [ + [ + 'store_id' => 1, + 'grand_total' => 280.00, + 'order_id' => $order->getId(), + 'email_sent' => 0, + 'send_email' => 0, + 'increment_id' => '123', + 'can_void_flag' => 1, + 'state' => 1 + ], + [ + 'store_id' => 1, + 'grand_total' => 450.00, + 'order_id' => $order->getId(), + 'email_sent' => 1, + 'send_email' => 1, + 'increment_id' => '456', + 'can_void_flag' => 1, + 'state' => 1 + ], + [ + 'store_id' => 0, + 'grand_total' => 10.00, + 'order_id' => $order->getId(), + 'email_sent' => 1, + 'send_email' => 1, + 'increment_id' => '789', + 'can_void_flag' => 0, + 'state' => 1 + ], + [ + 'store_id' => 1, + 'grand_total' => 1110.00, + 'order_id' => $order->getId(), + 'email_sent' => 1, + 'increment_id' => '012', + 'send_email' => 1, + 'can_void_flag' => 1, + 'state' => 0 + ], +]; + +/** @var array $creditMemoData */ +foreach ($invoices as $invoiceData) { + /** @var \Magento\Sales\Model\Order\Creditmemo $creditMemo */ + $invoice = $objectManager->create(\Magento\Sales\Model\Order\Invoice::class); + $invoice + ->setData($invoiceData) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_rollback.php new file mode 100644 index 00000000000..248f6469ad8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/invoice_list_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_item_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_item_list.php new file mode 100644 index 00000000000..06fe62997eb --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_item_list.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © 2016 Magento. 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(); + +$orderItems = [ + [ + 'product_id' => 1, + 'order_id' => $order->getId(), + 'base_price' => 90, + 'price' => 90, + 'row_total' => 92, + 'product_type' => 'configurable' + ], + [ + 'product_id' => 1, + 'base_price' => 100, + 'order_id' => $order->getId(), + 'price' => 100, + 'row_total' => 102, + 'product_type' => 'configurable' + ], + [ + 'product_id' => 12, + 'base_price' => 110, + 'order_id' => $order->getId(), + 'price' => 110, + 'row_total' => 112, + 'product_type' => 'virtual' + ], + [ + 'product_id' => 13, + '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(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php new file mode 100644 index 00000000000..ad8d1dc4e37 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; + +require 'order.php'; +/** @var Order $order */ +/** @var Order\Payment $payment */ +$orders = [ + [ + 'increment_id' => '100000002', + 'state' => \Magento\Sales\Model\Order::STATE_NEW, + 'status' => 'processing', + 'grand_total' => 120.00, + 'subtotal' => 120.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], + [ + 'increment_id' => '100000003', + 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, + 'status' => 'processing', + 'grand_total' => 140.00, + 'subtotal' => 140.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, + 'subtotal' => 140.00, + 'store_id' => 1, + 'website_id' => 1, + 'payment' => $payment + ], +]; + +/** @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 + ); + $order + ->setData($orderData) + ->save(); +} 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 new file mode 100644 index 00000000000..bec218557ce --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list_rollback.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * 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/order_payment_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_payment_list.php new file mode 100644 index 00000000000..96312eb6577 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_payment_list.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; + +require 'order.php'; +/** @var Order $order */ + +$payments = [ + [ + 'parent_id' => $order->getId(), + 'cc_exp_month' => '06', + 'cc_ss_start_year' => '2014', + 'method' => 'checkmo', + 'cc_last_4' => '123' + ], + [ + 'parent_id' => $order->getId(), + 'cc_exp_month' => '07', + 'cc_ss_start_year' => '2014', + 'method' => 'checkmo', + 'cc_last_4' => '456' + ], + [ + 'parent_id' => $order->getId(), + 'cc_exp_month' => '08', + 'cc_ss_start_year' => '2015', + 'method' => 'checkmo' + ], + [ + 'parent_id' => $order->getId(), + 'cc_exp_month' => '09', + 'cc_ss_start_year' => '2016', + 'method' => 'paypal_express' + ], +]; + +/** @var array $payments */ +foreach ($payments as $paymentData) { + /** @var $address \Magento\Sales\Model\Order\Payment */ + $payment = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Payment::class + ); + $payment + ->setData($paymentData) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list.php new file mode 100644 index 00000000000..fe84851c544 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; + +require 'order.php'; + +/** @var Order $order */ +/** @var Order\Payment $payment */ +/** @var Order\Item $orderItem */ + +$shipments = [ + [ + 'increment_id' => '100000001', + 'order_id' => $order->getId(), + 'shipping_address_id' => 1, + 'shipment_status' => \Magento\Sales\Model\Order\Shipment::STATUS_NEW, + 'store_id' => 1, + ], + [ + 'increment_id' => '100000002', + 'order_id' => $order->getId(), + 'shipping_address_id' => 3, + 'shipment_status' => \Magento\Sales\Model\Order\Shipment::STATUS_NEW, + 'store_id' => 1, + ], + [ + 'increment_id' => '100000003', + 'order_id' => $order->getId(), + 'shipping_address_id' => 3, + 'status' => \Magento\Sales\Model\Order\Shipment::STATUS_NEW, + 'store_id' => 1, + ], + [ + 'increment_id' => '100000004', + 'order_id' => $order->getId(), + 'shipping_address_id' => 4, + 'shipment_status' => 'closed', + 'store_id' => 1, + ], +]; + +/** @var array $shipmentData */ +foreach ($shipments as $shipmentData) { + /** @var $shipment \Magento\Sales\Model\Order\Shipment */ + $shipment = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Sales\Model\Order\Shipment::class + ); + /** @var \Magento\Sales\Model\Order\Shipment\Item $shipmentItem */ + $shipmentItem = $objectManager->create(\Magento\Sales\Model\Order\Shipment\Item::class); + $shipmentItem->setParentId($order->getId()); + $shipmentItem->setOrderItem($orderItem); + $shipment + ->setData($shipmentData) + ->addItem($shipmentItem) + ->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list_rollback.php new file mode 100644 index 00000000000..248f6469ad8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/shipment_list_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php new file mode 100644 index 00000000000..2a624638f42 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Model\Order; + +require 'transactions_list_rollback.php'; +require 'transactions_detailed.php'; + +/** @var Order $order */ +/** @var Order\Payment $payment */ + +$transactions = [ + [ + 'transaction_id' => 'trx_auth1', + 'is_transaction_closed' => 1, + 'order_id' => $order->getId(), + 'payment_id' => $payment->getId(), + 'parent_transaction_id' => 'trx_auth1', + 'txn_id' => 'aaabbbccc', + ], + [ + 'transaction_id' => 'trx_auth2', + 'is_transaction_closed' => 1, + 'parent_transaction_id' => 'trx_auth1', + 'order_id' => $order->getId(), + 'payment_id' => $payment->getId(), + 'txn_id' => '123456', + ], + [ + 'transaction_id' => 'trx_auth3', + 'is_transaction_closed' => 1, + 'parent_transaction_id' => 'trx_auth1', + 'order_id' => $order->getId(), + 'payment_id' => $payment->getId(), + 'txn_id' => 'wooooh', + ], + [ + 'transaction_id' => 'trx_auth4', + 'is_transaction_closed' => 1, + 'parent_transaction_id' => 'trx_auth2', + 'order_id' => $order->getId(), + 'payment_id' => $payment->getId(), + 'txn_id' => '--09--', + ] +]; + +/** @var array $transactionData */ +foreach ($transactions as $transactionData) { + $payment->addData($transactionData); + $payment->addTransaction(\Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE); +} + +$order->save(); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list_rollback.php new file mode 100644 index 00000000000..248f6469ad8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'default_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php index 51724d6dc12..33283739df9 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +require 'rules.php'; + $this->_collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class ); @@ -15,15 +17,15 @@ $coupon->setRuleId($items[0]->getId())->setCode('coupon_code')->setType(0)->save // type NO_COUPON with non actual previously generated coupon codes $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); -$coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_1')->setType(1)->save(); +$coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_1')->setType(1)->setIsPrimary(1)->save(); $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); $coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_2')->setType(1)->save(); -// type SPECIFIC with generated coupons +// type SPECIFIC with generated coupons $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); $coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_1')->setType(1)->save(); $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); -$coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_2')->setType(1)->save(); +$coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_2')->setType(1)->setIsPrimary(1)->save(); // type AUTO $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php index a9e13fc1f0c..a13cba853ce 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php @@ -3,6 +3,7 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ +require 'rules_rollback.php'; /** @var \Magento\SalesRule\Model\Rule $rule */ $rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); @@ -20,7 +21,10 @@ $rule->setName( 0 )->setWebsiteIds( '1' -)->setCustomerGroupIds( +) +->setUsesPerCoupon(2) +->setIsRss(1) +->setCustomerGroupIds( '0' )->setDiscountStep(0) ->save(); @@ -37,7 +41,10 @@ $rule->setName( 1 )->setCouponType( Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON -)->setUseAutoGeneration( +) +->setIsRss(1) +->setUsesPerCoupon(2) +->setUseAutoGeneration( 0 )->setWebsiteIds( '1' @@ -56,7 +63,8 @@ $rule->setName( 0 )->setIsAdvanced( 1 -)->setCouponType( +) +->setCouponType( Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC )->setUseAutoGeneration( 1 diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_rollback.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_rollback.php new file mode 100644 index 00000000000..7d6d06978e8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_rollback.php @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\SalesRule\Model\Rule; + +$collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\SalesRule\Model\ResourceModel\Rule\Collection::class); + +/** @var Rule $rule */ +foreach ($collection as $rule) { + $rule->delete(); +} diff --git a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php index 59e4fa29e1f..cfb126fd9ee 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Vault/Model/PaymentTokenRepositoryTest.php @@ -28,7 +28,7 @@ class PaymentTokenRepositoryTest extends \PHPUnit_Framework_TestCase /** @var SearchCriteriaBuilder */ private $searchCriteriaBuilder; - protected function setUp() + public function setUp() { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $this->repository = $objectManager->create(PaymentTokenRepository::class); diff --git a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php index 7185d224e33..e021dc7d437 100644 --- a/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php +++ b/dev/tests/integration/testsuite/Magento/Vault/_files/payment_tokens.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -include "customer.php"; +include "customer.php"; use Magento\Customer\Model\Customer; use Magento\Vault\Model\PaymentToken; -- GitLab From 39e784bf6d006ff295d665f99f5c701e2eeac473 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Mon, 8 Aug 2016 19:42:34 +0300 Subject: [PATCH 201/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales, SalesRule modules --- .../testsuite/Magento/Sales/_files/transactions_list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php index 2a624638f42..2c505d27dfc 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/transactions_list.php @@ -6,7 +6,7 @@ use Magento\Sales\Model\Order; -require 'transactions_list_rollback.php'; +require 'transactions_list_rollback.php'; require 'transactions_detailed.php'; /** @var Order $order */ -- GitLab From f625fc1e754dc2b386ceba23280ff3ebe8646446 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 8 Aug 2016 12:12:55 -0500 Subject: [PATCH 202/838] MAGETWO-55927: Eliminate @escapeNotVerified in UrlRewrite Module Applying escape functions in templates --- .../UrlRewrite/view/adminhtml/templates/categories.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml index 6a2508b048c..7aa02ab019c 100644 --- a/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml +++ b/app/code/Magento/UrlRewrite/view/adminhtml/templates/categories.phtml @@ -13,7 +13,7 @@ <div class="content content-category-tree"> <input type="hidden" name="categories" id="product_categories" value="" /> <?php if ($block->getRoot()): ?> - <div data-mage-init='<?php /* noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( + <div data-mage-init='<?php /* @noEscape */ echo $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode( [ 'categoryTree' => [ 'data' => $block->getTreeArray(), -- GitLab From 05bfa314da0ec67b5c425dda00b7b93f18fbd06c Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Mon, 8 Aug 2016 20:45:01 +0300 Subject: [PATCH 203/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales, SalesRule modules --- .../testsuite/Magento/Sales/_files/order_list.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php index ad8d1dc4e37..f124ce85419 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php @@ -5,10 +5,12 @@ */ use Magento\Sales\Model\Order; - require 'order.php'; /** @var Order $order */ /** @var Order\Payment $payment */ +/** @var Order\Item $orderItem */ +/** @var Order\Address $billingAddress */ +/** @var Order\Address $shippingAddress */ $orders = [ [ 'increment_id' => '100000002', @@ -16,6 +18,7 @@ $orders = [ 'status' => 'processing', 'grand_total' => 120.00, 'subtotal' => 120.00, + 'base_grand_total' => 120.00, 'store_id' => 1, 'website_id' => 1, 'payment' => $payment @@ -25,6 +28,7 @@ $orders = [ 'state' => \Magento\Sales\Model\Order::STATE_PROCESSING, 'status' => 'processing', 'grand_total' => 140.00, + 'base_grand_total' => 140.00, 'subtotal' => 140.00, 'store_id' => 0, 'website_id' => 0, @@ -35,6 +39,7 @@ $orders = [ '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, @@ -50,5 +55,8 @@ foreach ($orders as $orderData) { ); $order ->setData($orderData) + ->addItem($orderItem) + ->setBillingAddress($billingAddress) + ->setBillingAddress($shippingAddress) ->save(); } -- GitLab From b9039d920f746d57f157945ef4533b3f5c8b4a9d Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 8 Aug 2016 16:58:57 -0500 Subject: [PATCH 204/838] MAGETWO-56673: XssOutputValidatorTest fails on safe output Fixing test --- .../Utility/XssOutputValidator.php | 18 ++++++++++++++++-- .../Utility/_files/xss_safe.phtml | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php index 908489008b4..43f4c6eaa6b 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php +++ b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php @@ -17,16 +17,25 @@ class XssOutputValidator /** * Store origin for replacements + * * @var array */ private $origins = []; /** * Store replacements + * * @var array */ private $replacements = []; + /** + * Array of escape functions + * + * @var string[] + */ + private $escapeFunctions = ['escapeHtmlAttr', 'escapeUrl', 'escapeJs', 'escapeCss']; + /** * * @param string $file @@ -122,8 +131,13 @@ class XssOutputValidator foreach ($echoCommands as $echoCommand) { if ($this->isNotEscapeMarkedCommand($echoCommand)) { $echoCommand = preg_replace('/^(.*?)echo/sim', 'echo', $echoCommand); + $preparedEchoCommand = $this->prepareEchoCommand($echoCommand); + $isEscapeFunctionArgument = preg_match( + '/->(' . implode('|', $this->escapeFunctions) . ')\(.*?\)$/sim', + $preparedEchoCommand + ); $xssUnsafeCommands = array_filter( - explode('.', $this->prepareEchoCommand($echoCommand)), + $isEscapeFunctionArgument ? [$preparedEchoCommand] : explode('.', $preparedEchoCommand), [$this, 'isXssUnsafeCommand'] ); if (count($xssUnsafeCommands)) { @@ -202,7 +216,7 @@ class XssOutputValidator switch (true) { case preg_match( - '/->(escapeHtmlAttr|escapeUrl|escapeJs|escapeCss|.*html.*)\(/simU', + '/->(' . implode('|', $this->escapeFunctions) . '|.*html.*)\(/simU', $this->getLastMethod($command) ): return false; diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Utility/_files/xss_safe.phtml b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Utility/_files/xss_safe.phtml index d8163649679..ae9b09dd9c6 100644 --- a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Utility/_files/xss_safe.phtml +++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/Utility/_files/xss_safe.phtml @@ -44,3 +44,5 @@ echo $var; /* foreach ($block->getColumns() as $_column): ?> <col <?php echo $_column->getProperty() ?> /> <?php endforeach; */ ?> + +<?php echo $block->escapeHtmlAttr($block->getParamValue('title_' . $store['value'])); ?> -- GitLab From 6c6cc8610aca38c6dd6693208102fda3a990a58e Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 9 Aug 2016 10:25:58 +0300 Subject: [PATCH 205/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales, SalesRule modules --- .../SalesRule/Api/CouponRepositoryTest.php | 2 +- .../SalesRule/Api/RuleRepositoryTest.php | 2 +- .../Magento/SalesRule/_files/coupons.php | 6 +- .../SalesRule/_files/coupons_advanced.php | 32 +++++ .../Magento/SalesRule/_files/rules.php | 14 +-- .../SalesRule/_files/rules_advanced.php | 118 ++++++++++++++++++ 6 files changed, 157 insertions(+), 17 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_advanced.php create mode 100644 dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_advanced.php diff --git a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php index 832beb9779f..8b4452d44a0 100644 --- a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/CouponRepositoryTest.php @@ -99,7 +99,7 @@ class CouponRepositoryTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/SalesRule/_files/coupons.php + * @magentoApiDataFixture Magento/SalesRule/_files/coupons_advanced.php */ public function testGetListWithMultipleFiltersAndSorting() { diff --git a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php index bc8da5e2d82..c3299748e0c 100644 --- a/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/SalesRule/Api/RuleRepositoryTest.php @@ -172,7 +172,7 @@ class RuleRepositoryTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/SalesRule/_files/rules.php + * @magentoApiDataFixture Magento/SalesRule/_files/rules_advanced.php */ public function testGetListWithMultipleFiltersAndSorting() { diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php index 33283739df9..4ff08627ea9 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons.php @@ -4,8 +4,6 @@ * See COPYING.txt for license details. */ -require 'rules.php'; - $this->_collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class ); @@ -17,7 +15,7 @@ $coupon->setRuleId($items[0]->getId())->setCode('coupon_code')->setType(0)->save // type NO_COUPON with non actual previously generated coupon codes $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); -$coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_1')->setType(1)->setIsPrimary(1)->save(); +$coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_1')->setType(1)->save(); $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); $coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_2')->setType(1)->save(); @@ -25,7 +23,7 @@ $coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_2')->setType(1) $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); $coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_1')->setType(1)->save(); $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); -$coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_2')->setType(1)->setIsPrimary(1)->save(); +$coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_2')->setType(1)->save(); // type AUTO $coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_advanced.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_advanced.php new file mode 100644 index 00000000000..73b56b382b8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_advanced.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +require 'rules_advanced.php'; + +$this->_collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class +); +$items = array_values($this->_collection->getItems()); + +// type SPECIFIC with code +$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); +$coupon->setRuleId($items[0]->getId())->setCode('coupon_code')->setType(0)->save(); + +// type NO_COUPON with non actual previously generated coupon codes +$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); +$coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_1')->setType(1)->setIsPrimary(1)->save(); +$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); +$coupon->setRuleId($items[1]->getId())->setCode('autogenerated_2_2')->setType(1)->save(); + +// type SPECIFIC with generated coupons +$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); +$coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_1')->setType(1)->save(); +$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); +$coupon->setRuleId($items[2]->getId())->setCode('autogenerated_3_2')->setType(1)->setIsPrimary(1)->save(); + +// type AUTO +$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Coupon::class); +$coupon->setRuleId($items[3]->getId())->setCode('coupon_code_auto')->setType(0)->save(); diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php index a13cba853ce..a9e13fc1f0c 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -require 'rules_rollback.php'; /** @var \Magento\SalesRule\Model\Rule $rule */ $rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); @@ -21,10 +20,7 @@ $rule->setName( 0 )->setWebsiteIds( '1' -) -->setUsesPerCoupon(2) -->setIsRss(1) -->setCustomerGroupIds( +)->setCustomerGroupIds( '0' )->setDiscountStep(0) ->save(); @@ -41,10 +37,7 @@ $rule->setName( 1 )->setCouponType( Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON -) -->setIsRss(1) -->setUsesPerCoupon(2) -->setUseAutoGeneration( +)->setUseAutoGeneration( 0 )->setWebsiteIds( '1' @@ -63,8 +56,7 @@ $rule->setName( 0 )->setIsAdvanced( 1 -) -->setCouponType( +)->setCouponType( Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC )->setUseAutoGeneration( 1 diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_advanced.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_advanced.php new file mode 100644 index 00000000000..a13cba853ce --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/rules_advanced.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +require 'rules_rollback.php'; + +/** @var \Magento\SalesRule\Model\Rule $rule */ +$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); +$rule->setName( + '#1' +)->setIsActive( + 1 +)->setStopRulesProcessing( + 0 +)->setIsAdvanced( + 1 +)->setCouponType( + Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC +)->setUseAutoGeneration( + 0 +)->setWebsiteIds( + '1' +) +->setUsesPerCoupon(2) +->setIsRss(1) +->setCustomerGroupIds( + '0' +)->setDiscountStep(0) + ->save(); + +/** @var \Magento\SalesRule\Model\Rule $rule */ +$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); +$rule->setName( + '#2' +)->setIsActive( + 1 +)->setStopRulesProcessing( + 0 +)->setIsAdvanced( + 1 +)->setCouponType( + Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON +) +->setIsRss(1) +->setUsesPerCoupon(2) +->setUseAutoGeneration( + 0 +)->setWebsiteIds( + '1' +)->setCustomerGroupIds( + '0' +)->setDiscountStep(0) + ->save(); + +/** @var \Magento\SalesRule\Model\Rule $rule */ +$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); +$rule->setName( + '#3' +)->setIsActive( + 1 +)->setStopRulesProcessing( + 0 +)->setIsAdvanced( + 1 +) +->setCouponType( + Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC +)->setUseAutoGeneration( + 1 +)->setWebsiteIds( + '1' +)->setCustomerGroupIds( + '0' +)->setDiscountStep(0) + ->save(); + +/** @var \Magento\SalesRule\Model\Rule $rule */ +$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); +$rule->setName( + '#4' +)->setIsActive( + 1 +)->setStopRulesProcessing( + 0 +)->setIsAdvanced( + 1 +)->setCouponType( + Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO +)->setUseAutoGeneration( + 0 +)->setWebsiteIds( + '1' +)->setCustomerGroupIds( + '0' +)->setDiscountStep(0) + ->save(); + +/** @var \Magento\SalesRule\Model\Rule $rule */ +$rule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\SalesRule\Model\Rule::class); +$rule->setName( + '#5' +)->setIsActive( + 1 +)->setStopRulesProcessing( + 0 +)->setIsAdvanced( + 1 +)->setCouponType( + Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON +)->setUseAutoGeneration( + 0 +)->setWebsiteIds( + '1' +)->setCustomerGroupIds( + '0' +)->setDiscountStep(0) + ->save(); -- GitLab From 4f46d1f55a3ea5717ae0ba72eabf3fc389915066 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Tue, 9 Aug 2016 10:44:47 +0300 Subject: [PATCH 206/838] MAGETWO-55271: Cover with Functional Tests --- .../app/Magento/Setup/Test/Block/Extension/Grid.php | 2 ++ .../tests/app/Magento/Setup/Test/Block/Readiness.php | 2 +- .../app/Magento/Setup/Test/Repository/Extension.xml | 10 +++++++++- .../Test/TestCase/ExtensionMultipleUpdateTest.php | 2 +- .../Test/TestCase/ExtensionMultipleUpdateTest.xml | 6 +++--- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php index 3e1378f942d..49d0de9ceba 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Extension/Grid.php @@ -154,6 +154,8 @@ class Grid extends AbstractGrid */ public function findExtensionOnGrid(Extension $extension) { + sleep(3); + $this->_rootElement->waitUntil( function () { $message = $this->_rootElement->find($this->notFoundMessage)->isVisible(); diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php index 4654b4dc4c9..fefc5af46ed 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php @@ -41,7 +41,7 @@ class Readiness extends Block * * @var string */ - protected $removeExtension = '//li[contains(text(), \'%s\')]//button'; + protected $removeExtension = '//li//strong[contains(text(), \'%s\')]//..//button'; /** * 'Completed!' message. diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml b/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml index ae00a5b4dc7..319ae1a6ab8 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Repository/Extension.xml @@ -15,11 +15,19 @@ <dataset name="firstExtension"> <field name="extensionName" xsi:type="string">magento/module-customer-sample-data</field> + </dataset> + + <dataset name="secondExtension"> + <field name="extensionName" xsi:type="string">magento/module-theme-sample-data</field> + </dataset> + + <dataset name="thirdExtension"> + <field name="extensionName" xsi:type="string">magento/module-customer-sample-data</field> <field name="version" xsi:type="string">100.1.0-rc3</field> <field name="versionToUpdate" xsi:type="string">100.1.0</field> </dataset> - <dataset name="secondExtension"> + <dataset name="fourthExtension"> <field name="extensionName" xsi:type="string">magento/module-theme-sample-data</field> <field name="version" xsi:type="string">100.1.0-rc3</field> <field name="versionToUpdate" xsi:type="string">100.1.0</field> diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index ca36c33a949..0088c9645f7 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -35,7 +35,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest * @param $needAuthentication * @param array $extensions * @param array $removeExtensions - * + * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function test( diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml index f1d07e3b99c..b83cc068163 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.xml @@ -11,15 +11,15 @@ <data name="needAuthentication" xsi:type="boolean">false</data> <data name="extensions" xsi:type="array"> <item name="0" xsi:type="array"> - <item name="dataset" xsi:type="string">firstExtension</item> + <item name="dataset" xsi:type="string">thirdExtension</item> </item> <item name="1" xsi:type="array"> - <item name="dataset" xsi:type="string">secondExtension</item> + <item name="dataset" xsi:type="string">fourthExtension</item> </item> </data> <data name="removeExtensions" xsi:type="array"> <item name="0" xsi:type="array"> - <item name="dataset" xsi:type="string">firstExtension</item> + <item name="dataset" xsi:type="string">thirdExtension</item> </item> </data> </variation> -- GitLab From edf4c105c46f688cc9d86fa994fd3f73f00ab9f6 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 9 Aug 2016 11:01:04 +0300 Subject: [PATCH 207/838] MAGETWO-56577: Rename interface orderInvoice to invoiceOrder --- ...Interface.php => InvoiceOrderInterface.php} | 4 ++-- .../{OrderInvoice.php => InvoiceOrder.php} | 4 ++-- ...derInvoiceTest.php => InvoiceOrderTest.php} | 18 +++++++++--------- app/code/Magento/Sales/etc/di.xml | 2 +- app/code/Magento/Sales/etc/webapi.xml | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) rename app/code/Magento/Sales/Api/{OrderInvoiceInterface.php => InvoiceOrderInterface.php} (93%) rename app/code/Magento/Sales/Model/{OrderInvoice.php => InvoiceOrder.php} (98%) rename app/code/Magento/Sales/Test/Unit/Model/{OrderInvoiceTest.php => InvoiceOrderTest.php} (96%) diff --git a/app/code/Magento/Sales/Api/OrderInvoiceInterface.php b/app/code/Magento/Sales/Api/InvoiceOrderInterface.php similarity index 93% rename from app/code/Magento/Sales/Api/OrderInvoiceInterface.php rename to app/code/Magento/Sales/Api/InvoiceOrderInterface.php index 80fa6159afc..0f0ce459699 100644 --- a/app/code/Magento/Sales/Api/OrderInvoiceInterface.php +++ b/app/code/Magento/Sales/Api/InvoiceOrderInterface.php @@ -7,11 +7,11 @@ namespace Magento\Sales\Api; /** - * Class OrderInvoiceInterface + * Class InvoiceOrderInterface * * @api */ -interface OrderInvoiceInterface +interface InvoiceOrderInterface { /** * @param int $orderId diff --git a/app/code/Magento/Sales/Model/OrderInvoice.php b/app/code/Magento/Sales/Model/InvoiceOrder.php similarity index 98% rename from app/code/Magento/Sales/Model/OrderInvoice.php rename to app/code/Magento/Sales/Model/InvoiceOrder.php index b499b7028bc..d3f73a18b01 100644 --- a/app/code/Magento/Sales/Model/OrderInvoice.php +++ b/app/code/Magento/Sales/Model/InvoiceOrder.php @@ -9,7 +9,7 @@ namespace Magento\Sales\Model; use Magento\Framework\App\ResourceConnection; use Magento\Sales\Api\Data\InvoiceCommentCreationInterface; use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface; -use Magento\Sales\Api\OrderInvoiceInterface; +use Magento\Sales\Api\InvoiceOrderInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order\Config as OrderConfig; use Magento\Sales\Model\Order\Invoice\NotifierInterface; @@ -24,7 +24,7 @@ use Psr\Log\LoggerInterface; * Class InvoiceService * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class OrderInvoice implements OrderInvoiceInterface +class InvoiceOrder implements InvoiceOrderInterface { /** * @var ResourceConnection diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php similarity index 96% rename from app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php rename to app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php index bc36da112aa..412a05ff779 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php @@ -20,15 +20,15 @@ use Magento\Sales\Model\Order\InvoiceRepository; use Magento\Sales\Model\Order\InvoiceValidatorInterface; use Magento\Sales\Model\Order\OrderStateResolverInterface; use Magento\Sales\Model\Order\PaymentAdapterInterface; -use Magento\Sales\Model\OrderInvoice; +use Magento\Sales\Model\InvoiceOrder; use Psr\Log\LoggerInterface; /** - * Class OrderInvoiceTest + * Class InvoiceOrderTest * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class OrderInvoiceTest extends \PHPUnit_Framework_TestCase +class InvoiceOrderTest extends \PHPUnit_Framework_TestCase { /** * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject @@ -76,9 +76,9 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase private $notifierInterfaceMock; /** - * @var OrderInvoice|\PHPUnit_Framework_MockObject_MockObject + * @var InvoiceOrder|\PHPUnit_Framework_MockObject_MockObject */ - private $orderInvoice; + private $invoiceOrder; /** * @var InvoiceCreationArgumentsInterface|\PHPUnit_Framework_MockObject_MockObject @@ -172,7 +172,7 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $this->orderInvoice = new OrderInvoice( + $this->invoiceOrder = new InvoiceOrder( $this->resourceConnectionMock, $this->orderRepositoryMock, $this->invoiceDocumentFactoryMock, @@ -271,7 +271,7 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase $this->assertEquals( 2, - $this->orderInvoice->execute( + $this->invoiceOrder->execute( $orderId, $capture, $items, @@ -314,7 +314,7 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase ->with($this->invoiceMock, $this->orderMock) ->willReturn($errorMessages); - $this->orderInvoice->execute( + $this->invoiceOrder->execute( $orderId, $capture, $items, @@ -372,7 +372,7 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase $this->adapterInterface->expects($this->once()) ->method('rollBack'); - $this->orderInvoice->execute( + $this->invoiceOrder->execute( $orderId, $capture, $items, diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 383650c8688..4e405012371 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -88,7 +88,7 @@ <preference for="Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface" type="Magento\Sales\Model\ResourceModel\Order\CollectionFactory"/> <preference for="Magento\Sales\Api\Data\InvoiceCommentCreationInterface" type="Magento\Sales\Model\Order\Invoice\Comment"/> <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> - <preference for="Magento\Sales\Api\OrderInvoiceInterface" type="Magento\Sales\Model\OrderInvoice"/> + <preference for="Magento\Sales\Api\InvoiceOrderInterface" type="Magento\Sales\Model\InvoiceOrder"/> <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <type name="Magento\Sales\Model\ResourceModel\Report" shared="false"/> <type name="Magento\Sales\Model\Order\Pdf\Config\Reader"> diff --git a/app/code/Magento/Sales/etc/webapi.xml b/app/code/Magento/Sales/etc/webapi.xml index 8d1b1fda5bc..ed273c96f29 100644 --- a/app/code/Magento/Sales/etc/webapi.xml +++ b/app/code/Magento/Sales/etc/webapi.xml @@ -254,7 +254,7 @@ </resources> </route> <route url="/V1/order/:orderId/invoice" method="POST"> - <service class="Magento\Sales\Api\OrderInvoiceInterface" method="execute"/> + <service class="Magento\Sales\Api\InvoiceOrderInterface" method="execute"/> <resources> <resource ref="Magento_Sales::sales" /> </resources> -- GitLab From 7d2559aaf99ee47acaec2c8a658c03bbc2795977 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 9 Aug 2016 11:06:34 +0300 Subject: [PATCH 208/838] MAGETWO-56677: Create template and components for notification area --- .../Component/DataProvider/DataProvider.php | 38 ++++++++ .../view/adminhtml/layout/default.xml | 6 +- .../ui_component/notification_area.xml | 51 ++++++++++ .../adminhtml/web/js/grid/columns/message.js | 32 +++++++ .../web/template/grid/cells/message.html | 8 ++ .../adminhtml/web/template/grid/listing.html | 35 +++++++ .../web/css/source/_module.less | 92 +++++++++++++++++-- .../web/css/source/components/_messages.less | 12 ++- 8 files changed, 260 insertions(+), 14 deletions(-) create mode 100644 app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php create mode 100644 app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml create mode 100644 app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js create mode 100644 app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html create mode 100644 app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html diff --git a/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php b/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php new file mode 100644 index 00000000000..da7c0c885b1 --- /dev/null +++ b/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminNotification\Ui\Component\DataProvider; + +/** + * Class DataProvider + */ +class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider +{ + /** + * @var \Magento\AdminNotification\Model\ResourceModel\System\Message\Collection + */ + protected $collection; + /** + * DataProvider constructor. + * @param string $name + * @param string $primaryFieldName + * @param string $requestFieldName + * @param \Magento\AdminNotification\Model\ResourceModel\System\Message\CollectionFactory $messageCollectionFactory + * @param array $meta + * @param array $data + */ + public function __construct( + $name, + $primaryFieldName, + $requestFieldName, + \Magento\AdminNotification\Model\ResourceModel\System\Message\CollectionFactory $messageCollectionFactory, + array $meta = [], + array $data = [] + ) { + $this->collection = $messageCollectionFactory->create(); + parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data); + } +} diff --git a/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml b/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml index e3d32f17b63..780e48378a3 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminNotification/view/adminhtml/layout/default.xml @@ -8,11 +8,7 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="notifications"> - <block class="Magento\AdminNotification\Block\System\Messages" - name="system_messages" - as="system_messages" - before="-" - template="Magento_AdminNotification::system/messages.phtml"/> + <uiComponent name="notification_area"/> <block class="Magento\AdminNotification\Block\System\Messages\UnreadMessagePopup" name="unread_system_messages" as="unread_system_messages" diff --git a/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml b/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml new file mode 100644 index 00000000000..5b79a721391 --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="provider" xsi:type="string">notification_area.notification_area_data_source</item> + <item name="deps" xsi:type="string">notification_area.notification_area_data_source</item> + </item> + <item name="spinner" xsi:type="string">columns</item> + </argument> + <dataSource name="notification_area_data_source"> + <argument name="dataProvider" xsi:type="configurableObject"> + <argument name="class" xsi:type="string">Magento\AdminNotification\Ui\Component\DataProvider\DataProvider</argument> + <argument name="name" xsi:type="string">notification_area_data_source</argument> + <argument name="primaryFieldName" xsi:type="string">identity</argument> + <argument name="requestFieldName" xsi:type="string">identity</argument> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item> + <item name="update_url" xsi:type="url" path="mui/index/render"/> + <item name="storageConfig" xsi:type="array"> + <item name="indexField" xsi:type="string">identity</item> + </item> + </item> + </argument> + </argument> + </dataSource> + <columns name="columns"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="template" xsi:type="string">Magento_AdminNotification/grid/listing</item> + </item> + </argument> + <column name="created_at"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_AdminNotification/js/grid/columns/message</item> + <item name="label" xsi:type="string" translate="true"/> + <item name="dataType" xsi:type="string">text</item> + <item name="sorting" xsi:type="string">asc</item> + <item name="sortOrder" xsi:type="number">10</item> + </item> + </argument> + </column> + </columns> +</listing> diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js new file mode 100644 index 00000000000..0f3920051cd --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js @@ -0,0 +1,32 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'Magento_Ui/js/grid/columns/column', + 'underscore' +], function (Column, _) { + 'use strict'; + + return Column.extend({ + defaults: { + bodyTmpl: 'Magento_AdminNotification/grid/cells/message', + messageIndex: 'text', + fieldClass: { + message: true + } + }, + + getLabel: function (record) { + return record[this.messageIndex]; + }, + + getFieldClasses: function ($row) { + var status = $row.status || 'info'; + + this.fieldClass['message-' + status] = true; + + return this.fieldClass; + } + }); +}); diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html new file mode 100644 index 00000000000..171e96858a2 --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html @@ -0,0 +1,8 @@ +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div css="$col.getFieldClasses($row())" + html="$col.getLabel($row())"/> \ No newline at end of file diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html new file mode 100644 index 00000000000..bd407f5526a --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html @@ -0,0 +1,35 @@ +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<div id="system_messages" class="message-system<?php if ($lastCritical): ?> message-system-unread<?php endif; ?>"> + <div class="message-system-inner" data-bind="collapsible"> + <div class="message-system-short"> + <button data-bind="toggleCollapsible" class="message-system-action-dropdown"> + <span> + <translate args="'System Messages'"/>: + <text args="rows.length"/> + </span> + </button> + <div if="rows[0]" repeat="foreach: [rows[0]], item: '$row'" visible="!$collapsible.opened()"> + <fastForEach args="data: getVisible(), as: '$col'" > + <render args="$col.getBody()"/> + </fastForEach> + </div> + </div> + <div class="message-system-collapsible"> + <ul class="message-system-list"> + <li repeat="foreach: rows, item: '$row'"> + <fastForEach args="data: getVisible(), as: '$col'" > + <render args="$col.getBody()"/> + </fastForEach> + </li> + </ul> + <div class="message-system-summary"> + <a href="#" class="action__message-log">Some link</a> + </div> + </div> + </div> +</div> \ No newline at end of file diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 585269e14d6..0b9664f9f41 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -8,7 +8,14 @@ // _____________________________________________ @message-system__background-color: @color-lazy-sun; -@message-system-short-message__padding-vertical: 1.8rem; +@message-system__border-color: @color-gray82; +@message-system__color: @color-gray20; +@message-system-short-message__padding-vertical: 1.5rem; + +// Triangle marker +@message-system-triangle__height: .5rem; +@message-system-triangle__padding-right: 3rem; +@message-system-triangle__width: .8rem; // // Message system @@ -17,22 +24,39 @@ .message-system-inner { &:extend(.abs-clearfix all); background: @message-system__background-color; + border: solid @message-system__border-color; + border-width: 0 1px 1px; + position: relative; + + .message-error { + background: none; + } + + .message { + padding: 1.5rem 0 1.5rem @indent__l; - .message-system-list { - float: left; - width: 75%; + &:before { + left: 0; + } } } .message-system-list { + border-bottom: 1px solid @message-system__border-color; + border-top: 1px solid @message-system__border-color; list-style: none; - margin: 0; - padding: 0; + + li { + + &:not(:last-child) { + border-bottom: 1px dashed @message-system__border-color; + } + } } .message-system-short { overflow: hidden; - text-align: right; + padding: 0 1.5rem 0 @indent__l; .message-system-short-label { display: inline-block; @@ -40,7 +64,7 @@ } .message { - display: inline-block; + overflow: hidden; padding: @message-system-short-message__padding-vertical 2rem @message-system-short-message__padding-vertical 3.3rem; &:before { @@ -48,3 +72,55 @@ } } } + +.message-system-collapsible { + background: @message-system__background-color; + border: 1px solid @message-system__border-color; + border-top: 0; + display: none; + margin: 0 -1px; + padding: 0 @indent__l @message-system-short-message__padding-vertical; + position: absolute; + top: 100%; + z-index: @z-index-10; + + ._active & { + display: block; + } +} + +.message-system-action-dropdown { + .lib-button-reset(); + float: right; + margin-top: @message-system-short-message__padding-vertical; + position: relative; + + .action-toggle-triangle ( + @_dropdown__padding-right: @message-system-triangle__padding-right; + @_triangle__height: @message-system-triangle__height; + @_triangle__width: @message-system-triangle__width; + @_triangle__color: @message-system__color; + @_triangle__hover__color: darken(@message-system__color, 10%); + @_triangle__right: (@message-system-triangle__padding-right / 2) - (@message-system-triangle__width/ 2); + ); +} + +.message-system-summary { + text-align: right; + + .action__message-log { + display: inline-block; + margin: 0 @indent__xs; + + &:not(:last-child) { + border-right: 1px solid @message-system__border-color; + margin-right: .2rem; + padding-right: @indent__xs; + } + + &:last-child { + margin: 0; + padding: 0; + } + } +} \ No newline at end of file diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less index 9d9a4cab990..e955affe3fb 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_messages.less @@ -28,6 +28,9 @@ @alert-icon__warning__content: @icon-warning__content; @alert-icon__warning__color: @color-phoenix; +@alert-icon__progress__content: @icon-refresh__content; +@alert-icon__progress__color: @color-blue-dodger; + @alert-icon__success__content: @icon-check-mage__content; @alert-icon__success__color: @color-green-apple; @@ -93,6 +96,13 @@ } } +.message-progress { + &:before { + color: @alert-icon__progress__color; + content: @alert-icon__progress__content; + } +} + .message-error { background: @alert__error__background-color; @@ -128,4 +138,4 @@ .message-in-rating-edit { margin-left: 1.8rem; margin-right: 1.8rem; -} +} \ No newline at end of file -- GitLab From 1c79ecadd95f244d8a700dcbdc12b57d31838202 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 9 Aug 2016 11:07:27 +0300 Subject: [PATCH 209/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales, SalesRule modules --- .../testsuite/Magento/Webapi/JoinDirectivesTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php index 26bfc7af772..7045e12f742 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php @@ -44,6 +44,8 @@ class JoinDirectivesTest extends \Magento\TestFramework\TestCase\WebapiAbstract } /** + * Rollback rules + * @magentoApiDataFixture Magento/Sales/_files/rules_rollback.php * @magentoApiDataFixture Magento/Sales/_files/quote.php */ public function testGetList() -- GitLab From a1f9114fa2a3997135f7c847bc64dc5227533ab1 Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Tue, 9 Aug 2016 11:50:40 +0300 Subject: [PATCH 210/838] MAGETWO-56491: Introduce and implement ShipmentCreationArgumentsInterface --- .../ShipmentCreationArgumentsInterface.php | 32 ++++++++++++++++ .../Order/Shipment/CreationArguments.php | 37 +++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 1 + 3 files changed, 70 insertions(+) create mode 100644 app/code/Magento/Sales/Api/Data/ShipmentCreationArgumentsInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/CreationArguments.php diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCreationArgumentsInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCreationArgumentsInterface.php new file mode 100644 index 00000000000..f03d05be3c7 --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/ShipmentCreationArgumentsInterface.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Data; + +/** + * Interface for creation arguments for Shipment. + * + * @api + */ +interface ShipmentCreationArgumentsInterface extends \Magento\Framework\Api\ExtensibleDataInterface +{ + /** + * Gets existing extension attributes. + * + * @return \Magento\Sales\Api\Data\ShipmentCreationArgumentsExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Sets extension attributes. + * + * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsExtensionInterface $extensionAttributes + * + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentCreationArgumentsExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/CreationArguments.php b/app/code/Magento/Sales/Model/Order/Shipment/CreationArguments.php new file mode 100644 index 00000000000..8a43a73553e --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/CreationArguments.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Creation arguments for Shipment. + * + * @api + */ +class CreationArguments implements \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface +{ + /** + * @var \Magento\Sales\Api\Data\ShipmentCreationArgumentsExtensionInterface + */ + private $extensionAttributes; + + /** + * {@inheritdoc} + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * {@inheritdoc} + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentCreationArgumentsExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + return $this; + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 383650c8688..49fd2891fa9 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -30,6 +30,7 @@ <preference for="Magento\Sales\Api\Data\OrderStatusHistorySearchResultInterface" type="Magento\Sales\Model\ResourceModel\Order\Status\History\Collection"/> <preference for="Magento\Sales\Api\Data\ShipmentCommentInterface" type="Magento\Sales\Model\Order\Shipment\Comment"/> <preference for="Magento\Sales\Api\Data\ShipmentCommentSearchResultInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Comment\Collection"/> + <preference for="Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface" type="Magento\Sales\Model\Order\Shipment\CreationArguments"/> <preference for="Magento\Sales\Api\Data\ShipmentInterface" type="Magento\Sales\Model\Order\Shipment"/> <preference for="Magento\Sales\Api\Data\ShipmentItemInterface" type="Magento\Sales\Model\Order\Shipment\Item"/> <preference for="Magento\Sales\Api\Data\ShipmentItemSearchResultInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Item\Collection"/> -- GitLab From e212ca3efb309dc3e0c114695021c35294da6ad5 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 9 Aug 2016 12:01:17 +0300 Subject: [PATCH 211/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales, SalesRule modules --- .../testsuite/Magento/Webapi/JoinDirectivesTest.php | 2 +- .../integration/testsuite/Magento/Sales/_files/order_list.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php index 7045e12f742..f951316b606 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php @@ -45,7 +45,7 @@ class JoinDirectivesTest extends \Magento\TestFramework\TestCase\WebapiAbstract /** * Rollback rules - * @magentoApiDataFixture Magento/Sales/_files/rules_rollback.php + * @magentoApiDataFixture Magento/SalesRule/_files/rules_rollback.php * @magentoApiDataFixture Magento/Sales/_files/quote.php */ public function testGetList() diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php index f124ce85419..58ebcae4935 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_list.php @@ -5,6 +5,7 @@ */ use Magento\Sales\Model\Order; + require 'order.php'; /** @var Order $order */ /** @var Order\Payment $payment */ -- GitLab From 68e4dc1010f70b348b6183b5b2f1e6c005ab169f Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Tue, 9 Aug 2016 12:07:44 +0300 Subject: [PATCH 212/838] MAGETWO-55268: Upgrade/Check Requirements process --- setup/config/states.update.config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/config/states.update.config.php b/setup/config/states.update.config.php index 38e2ca5bff5..4e3970e086a 100644 --- a/setup/config/states.update.config.php +++ b/setup/config/states.update.config.php @@ -60,8 +60,8 @@ return [ 'url' => 'start-updater', 'templateUrl' => "$base/start-updater", 'controller' => 'startUpdaterController', - 'title' => "Component \n Update", - 'header' => 'Step 3: Component Update', + 'title' => "Extension \n Update", + 'header' => 'Step 3: Extension Update', 'nav' => true, 'order' => 6, 'type' => 'update' -- GitLab From e9124ad67e63d07104b534d46eb7f146ce00123a Mon Sep 17 00:00:00 2001 From: Olga Matviienko <omatviienko@magento.com> Date: Tue, 9 Aug 2016 12:06:47 +0300 Subject: [PATCH 213/838] MAGETWO-56677: Create template and components for notification area --- .../adminhtml/web/template/grid/listing.html | 4 +- .../web/css/source/_module.less | 53 ++++++++----------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html index bd407f5526a..e3922c8f167 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html @@ -13,7 +13,7 @@ <text args="rows.length"/> </span> </button> - <div if="rows[0]" repeat="foreach: [rows[0]], item: '$row'" visible="!$collapsible.opened()"> + <div class="message-system-short-wrapper" if="rows[0]" repeat="foreach: [rows[0]], item: '$row'" visible="!$collapsible.opened()"> <fastForEach args="data: getVisible(), as: '$col'" > <render args="$col.getBody()"/> </fastForEach> @@ -32,4 +32,4 @@ </div> </div> </div> -</div> \ No newline at end of file +</div> diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 0b9664f9f41..81640f6e145 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -33,44 +33,39 @@ } .message { - padding: 1.5rem 0 1.5rem @indent__l; + display: inline-block; + margin: 0 0 -3px; + overflow: hidden; + padding: @message-system-short-message__padding-vertical 0 @message-system-short-message__padding-vertical 3.3rem; &:before { - left: 0; + left: .3rem; } } + + .action-menu-item { + display: inline-block; + vertical-align: top; + padding: @message-system-short-message__padding-vertical 0 0; + } } .message-system-list { border-bottom: 1px solid @message-system__border-color; border-top: 1px solid @message-system__border-color; list-style: none; + margin: 0 0 1.5rem; li { - - &:not(:last-child) { - border-bottom: 1px dashed @message-system__border-color; + + li { + border-top: 1px dashed @message-system__border-color; } } } -.message-system-short { +.message-system-short-wrapper { overflow: hidden; padding: 0 1.5rem 0 @indent__l; - - .message-system-short-label { - display: inline-block; - padding: @message-system-short-message__padding-vertical .3rem @message-system-short-message__padding-vertical 1rem; - } - - .message { - overflow: hidden; - padding: @message-system-short-message__padding-vertical 2rem @message-system-short-message__padding-vertical 3.3rem; - - &:before { - left: .3rem; - } - } } .message-system-collapsible { @@ -78,9 +73,10 @@ border: 1px solid @message-system__border-color; border-top: 0; display: none; - margin: 0 -1px; + left: -1px; padding: 0 @indent__l @message-system-short-message__padding-vertical; position: absolute; + right: -1px; top: 100%; z-index: @z-index-10; @@ -92,7 +88,7 @@ .message-system-action-dropdown { .lib-button-reset(); float: right; - margin-top: @message-system-short-message__padding-vertical; + margin: @message-system-short-message__padding-vertical 0; position: relative; .action-toggle-triangle ( @@ -109,18 +105,15 @@ text-align: right; .action__message-log { + border-right: 1px solid @message-system__border-color; display: inline-block; - margin: 0 @indent__xs; - - &:not(:last-child) { - border-right: 1px solid @message-system__border-color; - margin-right: .2rem; - padding-right: @indent__xs; - } + margin: 0 .2rem 0 @indent__xs; + padding-right: @indent__xs; &:last-child { + border-right: 0; margin: 0; padding: 0; } } -} \ No newline at end of file +} -- GitLab From 0f0e3c570b09a5774bbff0097ef8c39b5d4deba5 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 9 Aug 2016 12:49:26 +0300 Subject: [PATCH 214/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Tax/etc/di.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 8ae648a6294..17c3487af63 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -125,14 +125,13 @@ <item name="ctc.customer_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CustomerTaxClass</item> <item name="ptc.product_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\ProductTaxClass</item> <item name="cd.customer_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CalculationData</item> - <item name="cd.product_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CalculationData</item> + <item name="cd.product_tax_class_id" xsi:type="object">Magento\Tax\Modsel\Api\SearchCriteria\JoinProcessor\CalculationData</item> </argument> <argument name="fieldMapping" xsi:type="array"> <item name="id" xsi:type="string">tax_calculation_rule_id</item> <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> - <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> @@ -143,7 +142,6 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> - <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> @@ -154,7 +152,6 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> - <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> -- GitLab From 7952629ce5f4fa9676640e30e5da00731c351829 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Tue, 9 Aug 2016 12:51:40 +0300 Subject: [PATCH 215/838] MAGETWO-55271: Cover with Functional Tests --- .../AssertMultipleUpdateSuccessMessage.php | 42 ------------------- .../TestCase/ExtensionMultipleUpdateTest.php | 12 +++--- 2 files changed, 6 insertions(+), 48 deletions(-) delete mode 100644 dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php deleted file mode 100644 index f840cd49fb6..00000000000 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Constraint/Extension/AssertMultipleUpdateSuccessMessage.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Setup\Test\Constraint\Extension; - -use Magento\Mtf\Constraint\AbstractConstraint; -use Magento\Setup\Test\Fixture\Extension; -use Magento\Setup\Test\Page\Adminhtml\SetupWizard; - -/** - * Class AssertMultipleUpdateSuccessMessage - */ -class AssertMultipleUpdateSuccessMessage extends AbstractConstraint -{ - /** - * Assert update of extensions is successful. - * - * @param SetupWizard $setupWizard - * @param Extension[] $extensions - * @param int $type - * @return void - */ - public function processAssert(SetupWizard $setupWizard, array $extensions, $type) - { - $assertSuccessMessage = $this->objectManager->get(AssertSuccessMessage::class); - foreach ($extensions as $extension) { - $assertSuccessMessage->processAssert($setupWizard, $extension, $type); - } - } - - /** - * Returns a string representation of successful assertion. - * - * @return string - */ - public function toString() - { - return "Extension Updater success message is correct."; - } -} diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index 0088c9645f7..bf74f107f16 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -9,7 +9,7 @@ use Magento\Mtf\Fixture\FixtureFactory; use Magento\Setup\Test\Constraint\AssertSuccessfulReadinessCheck; use Magento\Setup\Test\Constraint\Extension\AssertExtensionAndVersionCheck; use Magento\Setup\Test\Constraint\Extension\AssertFindExtensionOnGrid; -use Magento\Setup\Test\Constraint\Extension\AssertMultipleUpdateSuccessMessage; +use Magento\Setup\Test\Constraint\Extension\AssertMultipleSuccessMessage; use Magento\Setup\Test\Constraint\Extension\AssertSelectSeveralExtensions; use Magento\Setup\Test\Constraint\Extension\AssertSuccessMessage; use Magento\Setup\Test\Fixture\BackupOptions; @@ -30,7 +30,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest * @param AssertSuccessfulReadinessCheck $assertReadiness * @param AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck * @param AssertSuccessMessage $assertSuccessMessage - * @param AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage + * @param AssertMultipleSuccessMessage $assertMultipleSuccessMessage * @param AssertSelectSeveralExtensions $assertSelectSeveralExtensions * @param $needAuthentication * @param array $extensions @@ -46,7 +46,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest AssertSuccessfulReadinessCheck $assertReadiness, AssertExtensionAndVersionCheck $assertExtensionAndVersionCheck, AssertSuccessMessage $assertSuccessMessage, - AssertMultipleUpdateSuccessMessage $assertMultipleUpdateSuccessMessage, + AssertMultipleSuccessMessage $assertMultipleSuccessMessage, AssertSelectSeveralExtensions $assertSelectSeveralExtensions, $needAuthentication, array $extensions, @@ -80,7 +80,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest ); } - // Open Extension Grid with extensions to install + // Open Extension Grid with extensions to update $this->setupWizard->getSetupHome()->clickExtensionManager(); $this->setupWizard->getExtensionsGrid()->waitLoader(); $this->setupWizard->getExtensionsGrid()->clickUpdateButton(); @@ -104,13 +104,13 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest $this->backup($backupOptions); $this->setupWizard->getCreateBackup()->clickNext(); - // Start installing + // Start updating $this->setupWizard->getUpdaterExtension()->clickStartButton(); $updatedExtensions = array_diff_key($extensions, $removeExtensions); // Check success message - $assertMultipleUpdateSuccessMessage->processAssert( + $assertMultipleSuccessMessage->processAssert( $this->setupWizard, $updatedExtensions, AssertSuccessMessage::TYPE_UPDATE -- GitLab From 8c14edec477743467794a003ac16ec9dd6ff4b3a Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Tue, 9 Aug 2016 13:05:38 +0300 Subject: [PATCH 216/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../FilterProcessor/ProductCategoryFilter.php} | 4 ++-- app/code/Magento/Catalog/Model/ProductRepository.php | 2 +- .../FilterProcessor/ProductCategoryFilterTest.php} | 10 +++++----- app/code/Magento/Catalog/etc/di.xml | 10 +++++----- .../Customer/Model/ResourceModel/GroupRepository.php | 2 +- app/code/Magento/Customer/etc/di.xml | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) rename app/code/Magento/Catalog/Model/{Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php => Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilter.php} (85%) rename app/code/Magento/Catalog/Test/Unit/Model/{Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php => Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilterTest.php} (85%) diff --git a/app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilter.php similarity index 85% rename from app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php rename to app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilter.php index 48448128a28..91c3d894354 100644 --- a/app/code/Magento/Catalog/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php +++ b/app/code/Magento/Catalog/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilter.php @@ -3,14 +3,14 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor; +namespace Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; use Magento\Catalog\Model\ResourceModel\Product\Collection; use Magento\Framework\Api\Filter; use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; use Magento\Framework\Data\Collection\AbstractDb; -class CategoryFilter implements CustomFilterInterface +class ProductCategoryFilter implements CustomFilterInterface { /** * Apply category_id Filter to Product Collection diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 5022ffc272c..146668c9d63 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -685,7 +685,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessorComposite' + 'Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilterTest.php similarity index 85% rename from app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php rename to app/code/Magento/Catalog/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilterTest.php index 2b9df60ed28..86555f628a2 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Api/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilterTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/ProductCategoryFilterTest.php @@ -3,20 +3,20 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Catalog\Test\Unit\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor; +namespace Magento\Catalog\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; -use Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CategoryFilter; +use Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductCategoryFilter; use Magento\Catalog\Model\ResourceModel\Product\Collection; use Magento\Framework\Api\Filter; -class CategoryFilterTest extends \PHPUnit_Framework_TestCase +class ProductCategoryFilterTest extends \PHPUnit_Framework_TestCase { - /** @var CategoryFilter */ + /** @var ProductCategoryFilter */ private $model; protected function setUp() { - $this->model = new CategoryFilter(); + $this->model = new ProductCategoryFilter(); } public function testApply() diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index ad217866703..d6241a7eda4 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -805,17 +805,17 @@ </argument> </arguments> </type> - <virtualType name="Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="customFilters" xsi:type="array"> - <item name="category_id" xsi:type="object">Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CategoryFilter</item> + <item name="category_id" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\ProductCategoryFilter</item> </argument> </arguments> </virtualType> - <virtualType name="Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite"> <arguments> <argument name="processors" xsi:type="array"> - <item name="filters" xsi:type="object">Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="filters" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor</item> <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> </argument> @@ -823,7 +823,7 @@ </virtualType> <type name="Magento\Catalog\Model\ProductRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Product\Api\SearchCriteria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite</argument> </arguments> </type> </config> diff --git a/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php b/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php index 9c07801358b..e4d780d4e82 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php @@ -344,7 +344,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite' + 'Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 2ddf7426c91..38f7d7a0e26 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -320,7 +320,7 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> </arguments> </type> - <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <virtualType name="Magento\Customer\Model\Api\SearchCriteria\CollectionProcessor\GroupFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="fieldMapping" xsi:type="array"> <item name="code" xsi:type="string">customer_group_code</item> @@ -329,7 +329,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\SortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> + <virtualType name="Magento\Customer\Model\Api\SearchCriteria\CollectionProcessor\GroupSortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> <arguments> <argument name="fieldMapping" xsi:type="array"> <item name="code" xsi:type="string">customer_group_code</item> @@ -341,18 +341,18 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> <arguments> <argument name="processors" xsi:type="array"> - <item name="filters" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> - <item name="sorting" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="filters" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\CollectionProcessor\GroupFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\CollectionProcessor\GroupSortingProcessor</item> <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> </argument> </arguments> </virtualType> <type name="Magento\Customer\Model\ResourceModel\GroupRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Customer\Model\Group\Api\SearchCriteria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite</argument> </arguments> </type> </config> -- GitLab From e97264296dc84dd8d4502c86965c7c9da15398df Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 9 Aug 2016 13:21:03 +0300 Subject: [PATCH 217/838] MAGETWO-56677: Create template and components for notification area --- .../view/adminhtml/web/template/grid/listing.html | 3 --- .../Magento_AdminNotification/web/css/source/_module.less | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html index e3922c8f167..496e536e82e 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html @@ -27,9 +27,6 @@ </fastForEach> </li> </ul> - <div class="message-system-summary"> - <a href="#" class="action__message-log">Some link</a> - </div> </div> </div> </div> diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 81640f6e145..cad2321d3ce 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -78,7 +78,7 @@ position: absolute; right: -1px; top: 100%; - z-index: @z-index-10; + z-index: @z-index-8; ._active & { display: block; -- GitLab From 81572f0ad3546a97dca8552e539a704d2b9f2a05 Mon Sep 17 00:00:00 2001 From: Andrii Dimov <adimov@magento.com> Date: Tue, 9 Aug 2016 13:15:13 +0300 Subject: [PATCH 218/838] MAGETWO-56586: Implement Data and Schema Upgrade Test --- .../Test/Legacy/ModuleDBChangeTest.php | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php new file mode 100644 index 00000000000..e0628abec03 --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php @@ -0,0 +1,61 @@ +<?php +/** + * + * Scan source code for DB schema or data updates for patch releases in non-actual branches + * Backwards compatibility test + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Test\Legacy; + + +class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var string + */ + protected static $changedFilesPattern = __DIR__ . '/../_files/changed_files*'; + + /** + * @var string + */ + protected static $changedFileList = ''; + + /** + * Set changed files paths and list for all projects + */ + public static function setUpBeforeClass() + { + foreach (glob(self::$changedFilesPattern) as $changedFile) { + self::$changedFileList .= file_get_contents($changedFile) . PHP_EOL; + } + } + + /** + * Test changes for module.xml files + */ + public function testModuleXmlFiles() + { + preg_match_all('|etc/module\.xml$|mi', self::$changedFileList, $matches); + $this->assertEmpty( + reset($matches), + 'module.xml changes for patch releases in non-actual branches are not allowed:' . PHP_EOL . + implode(PHP_EOL, array_values(reset($matches))) + ); + } + + /** + * Test changes for files in Module Setup dir + */ + public function testModuleSetupFiles() + { + preg_match_all('|app/code/Magento/[^/]+/Setup/[^/]+$|mi', self::$changedFileList, $matches); + $this->assertEmpty( + reset($matches), + 'Code with changes for DB schema or data in non-actual branches are not allowed:' . PHP_EOL . + implode(PHP_EOL, array_values(reset($matches))) + ); + } +} -- GitLab From 02bcc00ec4a4919715ee7609ef516b1ee1c18f6e Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 9 Aug 2016 13:38:06 +0300 Subject: [PATCH 219/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Tax/etc/di.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 17c3487af63..8ae648a6294 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -125,13 +125,14 @@ <item name="ctc.customer_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CustomerTaxClass</item> <item name="ptc.product_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\ProductTaxClass</item> <item name="cd.customer_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CalculationData</item> - <item name="cd.product_tax_class_id" xsi:type="object">Magento\Tax\Modsel\Api\SearchCriteria\JoinProcessor\CalculationData</item> + <item name="cd.product_tax_class_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\CalculationData</item> </argument> <argument name="fieldMapping" xsi:type="array"> <item name="id" xsi:type="string">tax_calculation_rule_id</item> <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> @@ -142,6 +143,7 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> @@ -152,6 +154,7 @@ <item name="tax_rate_ids" xsi:type="string">tax_calculation_rate_id</item> <item name="customer_tax_class_ids" xsi:type="string">cd.customer_tax_class_id</item> <item name="product_tax_class_ids" xsi:type="string">cd.product_tax_class_id</item> + <item name="tax_calculation_rate_id" xsi:type="string">rate.tax_calculation_rate_id</item> </argument> </arguments> </virtualType> -- GitLab From 90bcc85d6881f3a76df9fb7f7cce6871b438ebc4 Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Tue, 9 Aug 2016 14:38:32 +0300 Subject: [PATCH 220/838] MAGETWO-56342: [Github] #5910 Braintree sandbox errors when using alternative Merchant Account ID --- .../Braintree/Gateway/Config/Config.php | 10 +++++++ .../Gateway/Request/PaymentDataBuilder.php | 2 +- .../Braintree/Model/Ui/ConfigProvider.php | 10 ++++++- .../Request/PaymentDataBuilderTest.php | 3 +-- .../Test/Unit/Model/Ui/ConfigProviderTest.php | 27 +++++++++++++++++-- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Braintree/Gateway/Config/Config.php b/app/code/Magento/Braintree/Gateway/Config/Config.php index 59cd8f7a75a..774b8e36536 100644 --- a/app/code/Magento/Braintree/Gateway/Config/Config.php +++ b/app/code/Magento/Braintree/Gateway/Config/Config.php @@ -193,4 +193,14 @@ class Config extends \Magento\Payment\Gateway\Config\Config } return $values; } + + /** + * Get Merchant account ID + * + * @return string + */ + public function getMerchantAccountId() + { + return $this->getValue(self::KEY_MERCHANT_ACCOUNT_ID); + } } diff --git a/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php b/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php index 9591d244654..dd038e1f9f2 100644 --- a/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php +++ b/app/code/Magento/Braintree/Gateway/Request/PaymentDataBuilder.php @@ -87,7 +87,7 @@ class PaymentDataBuilder implements BuilderInterface self::ORDER_ID => $order->getOrderIncrementId() ]; - $merchantAccountId = $this->config->getValue(Config::KEY_MERCHANT_ACCOUNT_ID); + $merchantAccountId = $this->config->getMerchantAccountId(); if (!empty($merchantAccountId)) { $result[self::MERCHANT_ACCOUNT_ID] = $merchantAccountId; } diff --git a/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php b/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php index 77c83707bfc..76788c3c145 100644 --- a/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php +++ b/app/code/Magento/Braintree/Model/Ui/ConfigProvider.php @@ -5,6 +5,7 @@ */ namespace Magento\Braintree\Model\Ui; +use Magento\Braintree\Gateway\Request\PaymentDataBuilder; use Magento\Checkout\Model\ConfigProviderInterface; use Magento\Braintree\Gateway\Config\Config; use Magento\Braintree\Model\Adapter\BraintreeAdapter; @@ -86,7 +87,14 @@ final class ConfigProvider implements ConfigProviderInterface public function getClientToken() { if (empty($this->clientToken)) { - $this->clientToken = $this->adapter->generate(); + $params = []; + + $merchantAccountId = $this->config->getMerchantAccountId(); + if (!empty($merchantAccountId)) { + $params[PaymentDataBuilder::MERCHANT_ACCOUNT_ID] = $merchantAccountId; + } + + $this->clientToken = $this->adapter->generate($params); } return $this->clientToken; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php index 47a9a49670e..7d30651c69e 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php @@ -133,8 +133,7 @@ class PaymentDataBuilderTest extends \PHPUnit_Framework_TestCase ->willReturnMap($additionalData); $this->configMock->expects(static::once()) - ->method('getValue') - ->with(Config::KEY_MERCHANT_ACCOUNT_ID) + ->method('getMerchantAccountId') ->willReturn(self::MERCHANT_ACCOUNT_ID); $this->paymentDO->expects(static::once()) diff --git a/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php b/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php index 9147b063258..04846f369eb 100644 --- a/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Model/Ui/ConfigProviderTest.php @@ -18,8 +18,8 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; class ConfigProviderTest extends \PHPUnit_Framework_TestCase { const SDK_URL = 'https://js.braintreegateway.com/v2/braintree.js'; - const CLIENT_TOKEN = 'token'; + const MERCHANT_ACCOUNT_ID = '245345'; /** * @var Config|MockObject @@ -76,11 +76,17 @@ class ConfigProviderTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Braintree\Model\Ui\ConfigProvider::getClientToken + * @dataProvider getClientTokenDataProvider */ - public function testGetClientToken() + public function testGetClientToken($merchantAccountId, $params) { + $this->config->expects(static::once()) + ->method('getMerchantAccountId') + ->willReturn($merchantAccountId); + $this->braintreeAdapter->expects(static::once()) ->method('generate') + ->with($params) ->willReturn(self::CLIENT_TOKEN); static::assertEquals(self::CLIENT_TOKEN, $this->configProvider->getClientToken()); @@ -140,4 +146,21 @@ class ConfigProviderTest extends \PHPUnit_Framework_TestCase ] ]; } + + /** + * @return array + */ + public function getClientTokenDataProvider() + { + return [ + [ + 'merchantAccountId' => '', + 'params' => [] + ], + [ + 'merchantAccountId' => self::MERCHANT_ACCOUNT_ID, + 'params' => ['merchantAccountId' => self::MERCHANT_ACCOUNT_ID] + ] + ]; + } } -- GitLab From ba882ebd0e3aea52f6bfca050e1848697e1e051f Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Tue, 9 Aug 2016 16:21:38 +0300 Subject: [PATCH 221/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../Magento/Catalog/Model/CategoryList.php | 53 +++++++------------ .../Test/Unit/Model/CategoryListTest.php | 43 +++++---------- app/code/Magento/Catalog/etc/di.xml | 5 ++ .../Magento/Catalog/Api/CategoryListTest.php | 14 +++++ 4 files changed, 52 insertions(+), 63 deletions(-) diff --git a/app/code/Magento/Catalog/Model/CategoryList.php b/app/code/Magento/Catalog/Model/CategoryList.php index b739c5bf463..fd457f6b311 100644 --- a/app/code/Magento/Catalog/Model/CategoryList.php +++ b/app/code/Magento/Catalog/Model/CategoryList.php @@ -14,8 +14,7 @@ use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; use Magento\Framework\Api\Search\FilterGroup; use Magento\Framework\Api\SearchCriteriaInterface; -use Magento\Framework\Api\SortOrder; -use Magento\Framework\App\ObjectManager; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; class CategoryList implements CategoryListInterface { @@ -39,22 +38,30 @@ class CategoryList implements CategoryListInterface */ private $categoryRepository; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param CollectionFactory $categoryCollectionFactory * @param JoinProcessorInterface $extensionAttributesJoinProcessor * @param CategorySearchResultsInterfaceFactory $categorySearchResultsFactory * @param CategoryRepositoryInterface $categoryRepository + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( CollectionFactory $categoryCollectionFactory, JoinProcessorInterface $extensionAttributesJoinProcessor, CategorySearchResultsInterfaceFactory $categorySearchResultsFactory, - CategoryRepositoryInterface $categoryRepository + CategoryRepositoryInterface $categoryRepository, + CollectionProcessorInterface $collectionProcessor = null ) { $this->categoryCollectionFactory = $categoryCollectionFactory; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; $this->categorySearchResultsFactory = $categorySearchResultsFactory; $this->categoryRepository = $categoryRepository; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -66,23 +73,7 @@ class CategoryList implements CategoryListInterface $collection = $this->categoryCollectionFactory->create(); $this->extensionAttributesJoinProcessor->process($collection); - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - - /** @var SortOrder $sortOrder */ - $sortOrders = $searchCriteria->getSortOrders(); - if ($sortOrders) { - foreach ($sortOrders as $sortOrder) { - $collection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() === SortOrder::SORT_ASC) ? SortOrder::SORT_ASC : SortOrder::SORT_DESC - ); - } - } - - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $this->collectionProcessor->process($searchCriteria, $collection); $items = []; foreach ($collection->getAllIds() as $id) { @@ -98,22 +89,18 @@ class CategoryList implements CategoryListInterface } /** - * Add filter group to collection + * Retrieve collection processor * - * @param FilterGroup $filterGroup - * @param Collection $collection - * @return void + * @deprecated + * @return CollectionProcessorInterface */ - private function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection) + private function getCollectionProcessor() { - $filters = $filterGroup->getFilters(); - if ($filters) { - $fields = []; - foreach ($filters as $filter) { - $conditionType = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $fields[] = ['attribute' => $filter->getField(), $conditionType => $filter->getValue()]; - } - $collection->addFieldToFilter($fields); + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite' + ); } + return $this->collectionProcessor; } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php b/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php index 4f72f43485b..5703f6fe2df 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php @@ -11,10 +11,8 @@ use Magento\Catalog\Model\Category; use Magento\Catalog\Model\CategoryList; use Magento\Catalog\Model\ResourceModel\Category\Collection; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; -use Magento\Framework\Api\Filter; -use Magento\Framework\Api\Search\FilterGroup; use Magento\Framework\Api\SearchCriteriaInterface; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory; @@ -49,6 +47,11 @@ class CategoryListTest extends \PHPUnit_Framework_TestCase */ private $categoryRepository; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessorMock; + protected function setUp() { $this->categoryCollectionFactory = $this->getMockBuilder(CollectionFactory::class) @@ -61,6 +64,8 @@ class CategoryListTest extends \PHPUnit_Framework_TestCase ->setMethods(['create']) ->getMock(); $this->categoryRepository = $this->getMock(CategoryRepositoryInterface::class); + $this->collectionProcessorMock = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMock(); $this->model = (new ObjectManager($this))->getObject( CategoryList::class, @@ -69,17 +74,13 @@ class CategoryListTest extends \PHPUnit_Framework_TestCase 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessor, 'categorySearchResultsFactory' => $this->categorySearchResultsFactory, 'categoryRepository' => $this->categoryRepository, + 'collectionProcessor' => $this->collectionProcessorMock, ] ); } public function testGetList() { - $fieldName = 'field_1'; - $value = 'value_1'; - $conditionType = 'eq'; - $currentPage = 2; - $pageSize = 1; $totalCount = 2; $categoryIdFirst = 1; $categoryIdSecond = 2; @@ -87,35 +88,17 @@ class CategoryListTest extends \PHPUnit_Framework_TestCase $categoryFirst = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock(); $categorySecond = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock(); - $filter = $this->getMockBuilder(Filter::class)->disableOriginalConstructor()->getMock(); - $filter->expects($this->atLeastOnce())->method('getConditionType')->willReturn($conditionType); - $filter->expects($this->atLeastOnce())->method('getField')->willReturn($fieldName); - $filter->expects($this->once())->method('getValue')->willReturn($value); - - $filterGroup = $this->getMockBuilder(FilterGroup::class)->disableOriginalConstructor()->getMock(); - $filterGroup->expects($this->once())->method('getFilters')->willReturn([$filter]); - - $sortOrder = $this->getMockBuilder(SortOrder::class)->disableOriginalConstructor()->getMock(); - $sortOrder->expects($this->once())->method('getField')->willReturn($fieldName); - $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC); - /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteria */ $searchCriteria = $this->getMock(SearchCriteriaInterface::class); - $searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]); - $searchCriteria->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $searchCriteria->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $searchCriteria->expects($this->once())->method('getSortOrders')->willReturn([$sortOrder]); $collection = $this->getMockBuilder(Collection::class)->disableOriginalConstructor()->getMock(); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->with([['attribute' => $fieldName, $conditionType => $value]]); - $collection->expects($this->once())->method('addOrder')->with($fieldName, SortOrder::SORT_ASC); - $collection->expects($this->once())->method('setCurPage')->with($currentPage); - $collection->expects($this->once())->method('setPageSize')->with($pageSize); $collection->expects($this->once())->method('getSize')->willReturn($totalCount); $collection->expects($this->once())->method('getAllIds')->willReturn([$categoryIdFirst, $categoryIdSecond]); + $this->collectionProcessorMock->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection); + $searchResult = $this->getMock(CategorySearchResultsInterface::class); $searchResult->expects($this->once())->method('setSearchCriteria')->with($searchCriteria); $searchResult->expects($this->once())->method('setItems')->with([$categoryFirst, $categorySecond]); diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index d6241a7eda4..70a1b8375fb 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -826,4 +826,9 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite</argument> </arguments> </type> + <type name="\Magento\Catalog\Model\CategoryList"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> + </arguments> + </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryListTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryListTest.php index e7d53148d84..872ab5e6f7c 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryListTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryListTest.php @@ -28,6 +28,20 @@ class CategoryListTest extends WebapiAbstract 'value' => 'Category 1', 'condition_type' => 'eq', ], + [ + 'field' => 'name', + 'value' => 'Category 1.1', + 'condition_type' => 'eq', + ], + ], + ], + [ + 'filters' => [ + [ + 'field' => 'level', + 'value' => 2, + 'condition_type' => 'eq', + ], ], ], ], -- GitLab From 30f7a8a23fe4d0ff917b5d2b4144c16f29e3121b Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Tue, 9 Aug 2016 16:34:12 +0300 Subject: [PATCH 222/838] MAGETWO-56692: Introduce extension attributes for InvoiceCreation Interfaces --- .../Data/InvoiceCommentCreationInterface.php | 16 +++ .../Api/Data/InvoiceCommentInterface.php | 2 +- .../Api/Data/InvoiceItemCreationInterface.php | 16 +++ .../Sales/Api/Data/InvoiceItemInterface.php | 15 --- .../Model/Order/Invoice/CommentCreation.php | 97 +++++++++++++++++++ .../Model/Order/Invoice/ItemCreation.php | 28 ++++++ app/code/Magento/Sales/etc/di.xml | 6 +- 7 files changed, 161 insertions(+), 19 deletions(-) create mode 100644 app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php index 85c114da382..34039310778 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php @@ -13,4 +13,20 @@ namespace Magento\Sales\Api\Data; */ interface InvoiceCommentCreationInterface extends \Magento\Sales\Api\Data\CommentInterface { + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface $extensionAttributes + ); } diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php index 1447fab476a..985d0dc8f14 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php @@ -13,7 +13,7 @@ namespace Magento\Sales\Api\Data; * @api */ interface InvoiceCommentInterface extends \Magento\Framework\Api\ExtensibleDataInterface, -\Magento\Sales\Api\Data\InvoiceCommentCreationInterface + \Magento\Sales\Api\Data\CommentInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php index 4b5c6fa2c61..d4b250ed911 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php @@ -15,4 +15,20 @@ namespace Magento\Sales\Api\Data; */ interface InvoiceItemCreationInterface extends LineItemInterface { + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface $extensionAttributes + ); } diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php index ecdcd07bc0c..011c613d145 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php @@ -448,19 +448,4 @@ interface InvoiceItemInterface extends \Magento\Sales\Api\Data\InvoiceItemCreati * @return $this */ public function setBaseDiscountTaxCompensationAmount($amount); - - /** - * Retrieve existing extension attributes object or create a new one. - * - * @return \Magento\Sales\Api\Data\InvoiceItemExtensionInterface|null - */ - public function getExtensionAttributes(); - - /** - * Set an extension attributes object. - * - * @param \Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes - * @return $this - */ - public function setExtensionAttributes(\Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes); } diff --git a/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php b/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php new file mode 100644 index 00000000000..58ad64a0e58 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order\Invoice; + +use Magento\Sales\Api\Data\InvoiceCommentCreationInterface; + +/** + * Class InvoiceCommentCreation + */ +class CommentCreation implements InvoiceCommentCreationInterface +{ + + /** + * @var string + */ + private $comment; + + /** + * @var int + */ + private $isVisibleOnFront; + + /** + * @var \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface + */ + private $extensionAttributes; + + /** + * Gets the comment for the invoice. + * + * @return string Comment. + */ + public function getComment() + { + return $this->comment; + } + + /** + * Sets the comment for the invoice. + * + * @param string $comment + * @return $this + */ + public function setComment($comment) + { + $this->comment = $comment; + return $this; + } + + /** + * Gets the is-visible-on-storefront flag value for the invoice. + * + * @return int Is-visible-on-storefront flag value. + */ + public function getIsVisibleOnFront() + { + return $this->isVisibleOnFront; + } + + /** + * Sets the is-visible-on-storefront flag value for the invoice. + * + * @param int $isVisibleOnFront + * @return $this + */ + public function setIsVisibleOnFront($isVisibleOnFront) + { + $this->isVisibleOnFront = $isVisibleOnFront; + return $this; + } + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface|null + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + } +} diff --git a/app/code/Magento/Sales/Model/Order/Invoice/ItemCreation.php b/app/code/Magento/Sales/Model/Order/Invoice/ItemCreation.php index abc19c3aaa7..26d8d7ae6ca 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/ItemCreation.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/ItemCreation.php @@ -23,6 +23,11 @@ class ItemCreation implements InvoiceItemCreationInterface */ private $qty; + /** + * @var \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface + */ + private $extensionAttributes; + /** * {@inheritdoc} */ @@ -54,4 +59,27 @@ class ItemCreation implements InvoiceItemCreationInterface { $this->qty = $qty; } + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface|null + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\InvoiceItemCreationExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + return $this; + } } diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 383650c8688..d16fdc11c29 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -49,7 +49,9 @@ <preference for="Magento\Sales\Api\InvoiceItemRepositoryInterface" type="Magento\Sales\Api\Data\InvoiceItem\Repository"/> <preference for="Magento\Sales\Api\InvoiceRepositoryInterface" type="Magento\Sales\Model\Order\InvoiceRepository"/> <preference for="Magento\Sales\Api\InvoiceManagementInterface" type="Magento\Sales\Model\Service\InvoiceService"/> - <preference for="Magento\Sales\Api\InvoiceCreationArgumentsInterface" type="Magento\Sales\Model\Order\Invoice\CreationArguments"/> + <preference for="Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface" type="Magento\Sales\Model\Order\Invoice\CreationArguments"/> + <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> + <preference for="Magento\Sales\Api\Data\InvoiceCommentCreationInterface" type="Magento\Sales\Model\Order\Invoice\CommentCreation"/> <preference for="Magento\Sales\Api\OrderAddressRepositoryInterface" type="Magento\Sales\Model\Order\AddressRepository"/> <preference for="Magento\Sales\Api\OrderCustomerManagementInterface" type="Magento\Sales\Model\Order\CustomerManagement"/> <preference for="Magento\Sales\Api\OrderItemRepositoryInterface" type="Magento\Sales\Model\Order\ItemRepository"/> @@ -86,8 +88,6 @@ <preference for="Magento\Sales\Model\Spi\ShipmentTrackResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Track"/> <preference for="Magento\Sales\Model\Spi\TransactionResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Payment\Transaction"/> <preference for="Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface" type="Magento\Sales\Model\ResourceModel\Order\CollectionFactory"/> - <preference for="Magento\Sales\Api\Data\InvoiceCommentCreationInterface" type="Magento\Sales\Model\Order\Invoice\Comment"/> - <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> <preference for="Magento\Sales\Api\OrderInvoiceInterface" type="Magento\Sales\Model\OrderInvoice"/> <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <type name="Magento\Sales\Model\ResourceModel\Report" shared="false"/> -- GitLab From a9be1d142839e03dc159285444ee070126a95f7c Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Tue, 9 Aug 2016 17:18:58 +0300 Subject: [PATCH 223/838] MAGETWO-56692: Introduce extension attributes for InvoiceCreation Interfaces --- .../Sales/Api/Data/CommentInterface.php | 10 ++++ .../Sales/Api/Data/EntityInterface.php | 52 +++++++++++++++++++ .../Api/Data/InvoiceCommentInterface.php | 48 +---------------- .../Sales/Api/Data/InvoiceItemInterface.php | 4 +- 4 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 app/code/Magento/Sales/Api/Data/EntityInterface.php diff --git a/app/code/Magento/Sales/Api/Data/CommentInterface.php b/app/code/Magento/Sales/Api/Data/CommentInterface.php index d7021dc9f95..fcab7863193 100644 --- a/app/code/Magento/Sales/Api/Data/CommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/CommentInterface.php @@ -12,6 +12,16 @@ namespace Magento\Sales\Api\Data; */ interface CommentInterface { + /* + * Is-visible-on-storefront flag. + */ + const IS_VISIBLE_ON_FRONT = 'is_visible_on_front'; + + /* + * Comment. + */ + const COMMENT = 'comment'; + /** * Gets the comment for the invoice. * diff --git a/app/code/Magento/Sales/Api/Data/EntityInterface.php b/app/code/Magento/Sales/Api/Data/EntityInterface.php new file mode 100644 index 00000000000..30eb054bc2c --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/EntityInterface.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Data; + +/** + * Interface EntityInterface + */ +interface EntityInterface +{ + /* + * Entity ID. + */ + const ENTITY_ID = 'entity_id'; + + /* + * Created-at timestamp. + */ + const CREATED_AT = 'created_at'; + + /** + * Gets the created-at timestamp for the invoice. + * + * @return string|null Created-at timestamp. + */ + public function getCreatedAt(); + + /** + * Sets the created-at timestamp for the invoice. + * + * @param string $createdAt timestamp + * @return $this + */ + public function setCreatedAt($createdAt); + + /** + * Gets the ID for the invoice. + * + * @return int|null Invoice ID. + */ + public function getEntityId(); + + /** + * Sets entity ID. + * + * @param int $entityId + * @return $this + */ + public function setEntityId($entityId); +} \ No newline at end of file diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php index 985d0dc8f14..b81a7b3b07b 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php @@ -13,15 +13,11 @@ namespace Magento\Sales\Api\Data; * @api */ interface InvoiceCommentInterface extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\CommentInterface + \Magento\Sales\Api\Data\CommentInterface, \Magento\Sales\Api\Data\EntityInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. */ - /* - * Entity ID. - */ - const ENTITY_ID = 'entity_id'; /* * Parent ID. */ @@ -30,48 +26,6 @@ interface InvoiceCommentInterface extends \Magento\Framework\Api\ExtensibleDataI * Is-customer-notified flag. */ const IS_CUSTOMER_NOTIFIED = 'is_customer_notified'; - /* - * Is-visible-on-storefront flag. - */ - const IS_VISIBLE_ON_FRONT = 'is_visible_on_front'; - /* - * Comment. - */ - const COMMENT = 'comment'; - /* - * Created-at timestamp. - */ - const CREATED_AT = 'created_at'; - - /** - * Gets the created-at timestamp for the invoice. - * - * @return string|null Created-at timestamp. - */ - public function getCreatedAt(); - - /** - * Sets the created-at timestamp for the invoice. - * - * @param string $createdAt timestamp - * @return $this - */ - public function setCreatedAt($createdAt); - - /** - * Gets the ID for the invoice. - * - * @return int|null Invoice ID. - */ - public function getEntityId(); - - /** - * Sets entity ID. - * - * @param int $entityId - * @return $this - */ - public function setEntityId($entityId); /** * Gets the is-customer-notified flag value for the invoice. diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php index 011c613d145..7ea3646c0bb 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php @@ -11,8 +11,8 @@ namespace Magento\Sales\Api\Data; * An invoice is a record of the receipt of payment for an order. An invoice item is a purchased item in an invoice. * @api */ -interface InvoiceItemInterface extends \Magento\Sales\Api\Data\InvoiceItemCreationInterface, -\Magento\Framework\Api\ExtensibleDataInterface +interface InvoiceItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface, + \Magento\Sales\Api\Data\LineItemInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. -- GitLab From 0cf3a3b36d8d71f90985dde72664d517c0e832a0 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 9 Aug 2016 10:27:45 -0500 Subject: [PATCH 224/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module Applying escape functions in templates --- lib/internal/Magento/Framework/Escaper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 64566aea2d2..fe88e2b0792 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -54,7 +54,7 @@ class Escaper public function escapeHtmlAttr($string, $escapeSingleQuote = true) { if ($escapeSingleQuote) { - return $this->getEscaper()->escapeHtmlAttr($string); + return $this->getEscaper()->escapeHtmlAttr((string) $string); } return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false); } -- GitLab From 9a7c307ad4b1960f6db81f8be1e4f598c5771a13 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 9 Aug 2016 10:33:24 -0500 Subject: [PATCH 225/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../Magento/Cookie/view/frontend/templates/html/notices.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 61afce2979d..cbf1d3ad2b2 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -27,7 +27,7 @@ "#notice-cookie-block": { "cookieNotices": { "cookieAllowButtonSelector": "#btn-cookie-allow", - "cookieName": "<?php echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", + "cookieName": "<?php /* @noEscape */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", "cookieValue": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getAcceptedSaveCookiesWebsiteIds() ?>, "cookieLifetime": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getCookieRestrictionLifetime()?>, "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" -- GitLab From 72098ea6c7c009da4718825bdf565dc8fd57b610 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 9 Aug 2016 12:05:49 -0500 Subject: [PATCH 226/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../Helper/Catalog/Product/Configuration.php | 1 + .../Block/Customer/Wishlist/Item/Options.php | 16 +++++++++++++++- .../view/frontend/templates/options_list.phtml | 6 +----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php b/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php index d452888fa54..91a3ec60808 100644 --- a/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php +++ b/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php @@ -142,6 +142,7 @@ class Configuration extends AbstractHelper implements ConfigurationInterface . $this->pricingHelper->currency( $this->getSelectionFinalPrice($item, $bundleSelection) ); + $option['html_value'] = true; } } diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php index a5fa5f1dc5c..4d69f176fcf 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php @@ -103,7 +103,21 @@ class Options extends \Magento\Wishlist\Block\AbstractBlock $data = $this->getOptionsRenderCfg($item->getProduct()->getTypeId()); $helper = $this->_helperPool->get($data['helper']); - return $helper->getOptions($item); + $options = $helper->getOptions($item); + foreach ($options as $index => $option) { + if (is_array($option) && array_key_exists('value', $option)) { + if (is_array($option['value'])) { + $option['value'] = nl2br(implode("\n", $option['value'])); + } + + if (!(array_key_exists('html_value', $option) && $option['html_value'] === true)) { + $option['value'] = $this->escapeHtml($option['value']); + } + $options[$index]['value'] = $option['value']; + } + } + + return $options; } /** diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index 2221b882b47..7a761e1b3d2 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -19,11 +19,7 @@ <?php foreach ($options as $option): ?> <dt class="label"><?php echo $block->escapeHtml($option['label']) ?></dt> <dd class="values"> - <?php if (is_array($option['value'])): ?> - <?php /* @noEscape */ echo nl2br(implode("\n", $option['value'])) ?> - <?php else: ?> - <?php echo $block->escapeHtml($option['value']) ?> - <?php endif; ?> + <?php /* @noEscape */ echo $option['value'] ?> </dd> <?php endforeach; ?> </dl> -- GitLab From 4bec5501003df7ee83bdbd210ac799db7264d1b0 Mon Sep 17 00:00:00 2001 From: Sergey Semenov <ssemenov@magento.com> Date: Tue, 9 Aug 2016 22:02:04 +0300 Subject: [PATCH 227/838] MAGETWO-56079: SearchCriteria Unified Processing for Cms, Customer and Eav modules --- .../FilterProcessor/BlockStoreFilter.php | 28 +++ .../FilterProcessor/PageStoreFilter.php | 28 +++ .../Magento/Cms/Model/BlockRepository.php | 72 +++--- app/code/Magento/Cms/Model/PageRepository.php | 73 +++--- .../FilterProcessor/BlockStoreFilterTest.php | 43 ++++ .../FilterProcessor/PageStoreFilterTest.php | 43 ++++ .../Test/Unit/Model/BlockRepositoryTest.php | 71 +++--- .../Test/Unit/Model/PageRepositoryTest.php | 76 +++--- app/code/Magento/Cms/etc/di.xml | 42 ++++ .../Model/ResourceModel/AddressRepository.php | 52 ++-- .../ResourceModel/AddressRepositoryTest.php | 53 ++-- app/code/Magento/Customer/etc/di.xml | 5 + .../AttributeGroupAttributeSetIdFilter.php | 30 +++ .../AttributeGroupCodeFilter.php | 29 +++ .../FilterProcessor/AttributeIdFilter.php | 36 +++ .../AttributeSetEntityTypeCodeFilter.php | 47 ++++ .../Eav/Model/Attribute/GroupRepository.php | 36 ++- .../Magento/Eav/Model/AttributeRepository.php | 48 ++-- .../Eav/Model/AttributeSetRepository.php | 39 ++- .../AttributeGroupCodeFilterTest.php | 65 +++++ .../FilterProcessor/AttributeIdFilterTest.php | 69 ++++++ .../AttributeSetEntityTypeCodeFilterTest.php | 88 +++++++ .../AttributeSetIdFilterTest.php | 64 +++++ .../Model/Attribute/GroupRepositoryTest.php | 68 +++-- .../Unit/Model/AttributeRepositoryTest.php | 233 ++++++++++++++++++ .../Unit/Model/AttributeSetRepositoryTest.php | 147 ++++++----- app/code/Magento/Eav/etc/di.xml | 71 ++++++ .../Magento/Cms/Api/BlockRepositoryTest.php | 54 +++- .../Magento/Cms/Api/PageRepositoryTest.php | 59 ++++- .../Eav/Api/AttributeSetRepositoryTest.php | 88 ++++--- .../ResourceModel/AddressRepositoryTest.php | 44 ++-- .../Model/Attribute/GroupRepositoryTest.php | 85 +++++++ .../Eav/Model/AttributeRepositoryTest.php | 74 ++++++ .../Eav/_files/attribute_for_search.php | 61 +++++ .../Eav/_files/attribute_group_for_search.php | 55 +++++ .../Eav/_files/attribute_set_for_search.php | 41 +++ .../attribute_set_for_search_rollback.php | 22 ++ 37 files changed, 1817 insertions(+), 422 deletions(-) create mode 100644 app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilter.php create mode 100644 app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilter.php create mode 100644 app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilterTest.php create mode 100644 app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilterTest.php create mode 100644 app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php create mode 100644 app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php create mode 100644 app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php create mode 100644 app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php create mode 100644 app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php create mode 100644 app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php create mode 100644 app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php create mode 100644 app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php create mode 100644 app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Eav/Model/AttributeRepositoryTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Eav/_files/attribute_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Eav/_files/attribute_group_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search.php create mode 100644 dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search_rollback.php diff --git a/app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilter.php b/app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilter.php new file mode 100644 index 00000000000..bf2a6b2a5a5 --- /dev/null +++ b/app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilter.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class BlockStoreFilter implements CustomFilterInterface +{ + /** + * Apply custom store filter to collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + /** @var \Magento\Cms\Model\ResourceModel\Block\Collection $collection */ + $collection->addStoreFilter($filter->getValue(), false); + + return true; + } +} diff --git a/app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilter.php b/app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilter.php new file mode 100644 index 00000000000..20ad94e6975 --- /dev/null +++ b/app/code/Magento/Cms/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilter.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class PageStoreFilter implements CustomFilterInterface +{ + /** + * Apply custom store filter to collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + /** @var \Magento\Cms\Model\ResourceModel\Page\Collection $collection */ + $collection->addStoreFilter($filter->getValue(), false); + + return true; + } +} diff --git a/app/code/Magento/Cms/Model/BlockRepository.php b/app/code/Magento/Cms/Model/BlockRepository.php index dd9e1eec776..59e84c476d0 100644 --- a/app/code/Magento/Cms/Model/BlockRepository.php +++ b/app/code/Magento/Cms/Model/BlockRepository.php @@ -8,7 +8,7 @@ namespace Magento\Cms\Model; use Magento\Cms\Api\Data; use Magento\Cms\Api\BlockRepositoryInterface; use Magento\Framework\Api\DataObjectHelper; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\CouldNotDeleteException; use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\NoSuchEntityException; @@ -63,6 +63,11 @@ class BlockRepository implements BlockRepositoryInterface */ private $storeManager; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param ResourceBlock $resource * @param BlockFactory $blockFactory @@ -72,6 +77,7 @@ class BlockRepository implements BlockRepositoryInterface * @param DataObjectHelper $dataObjectHelper * @param DataObjectProcessor $dataObjectProcessor * @param StoreManagerInterface $storeManager + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( ResourceBlock $resource, @@ -81,7 +87,8 @@ class BlockRepository implements BlockRepositoryInterface Data\BlockSearchResultsInterfaceFactory $searchResultsFactory, DataObjectHelper $dataObjectHelper, DataObjectProcessor $dataObjectProcessor, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + CollectionProcessorInterface $collectionProcessor = null ) { $this->resource = $resource; $this->blockFactory = $blockFactory; @@ -91,6 +98,7 @@ class BlockRepository implements BlockRepositoryInterface $this->dataBlockFactory = $dataBlockFactory; $this->dataObjectProcessor = $dataObjectProcessor; $this->storeManager = $storeManager; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -139,27 +147,11 @@ class BlockRepository implements BlockRepositoryInterface */ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $criteria) { - $searchResults = $this->searchResultsFactory->create(); - $searchResults->setSearchCriteria($criteria); - /** @var \Magento\Cms\Model\ResourceModel\Block\Collection $collection */ $collection = $this->blockCollectionFactory->create(); - foreach ($criteria->getFilterGroups() as $filterGroup) { - $this->addFilterGroupToCollection($filterGroup, $collection); - } - $searchResults->setTotalCount($collection->getSize()); - $sortOrders = $criteria->getSortOrders(); - if ($sortOrders) { - foreach ($sortOrders as $sortOrder) { - $collection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - $collection->setCurPage($criteria->getCurrentPage()); - $collection->setPageSize($criteria->getPageSize()); + $this->collectionProcessor->process($criteria, $collection); + $blocks = []; /** @var Block $blockModel */ foreach ($collection as $blockModel) { @@ -174,7 +166,12 @@ class BlockRepository implements BlockRepositoryInterface \Magento\Cms\Api\Data\BlockInterface::class ); } + + /** @var Data\BlockSearchResultsInterface $searchResults */ + $searchResults = $this->searchResultsFactory->create(); + $searchResults->setSearchCriteria($criteria); $searchResults->setItems($blocks); + $searchResults->setTotalCount($collection->getSize()); return $searchResults; } @@ -209,31 +206,18 @@ class BlockRepository implements BlockRepositoryInterface } /** - * Helper function that adds a FilterGroup to the collection. + * Retrieve collection processor * - * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup - * @param \Magento\Cms\Model\ResourceModel\Block\Collection $collection - * @return void - * @throws \Magento\Framework\Exception\InputException - */ - private function addFilterGroupToCollection( - \Magento\Framework\Api\Search\FilterGroup $filterGroup, - \Magento\Cms\Model\ResourceModel\Block\Collection $collection - ) { - $fields = []; - $conditions = []; - foreach ($filterGroup->getFilters() as $filter) { - if ($filter->getField() === 'store_id') { - $collection->addStoreFilter($filter->getValue(), false); - continue; - } - $condition = $filter->getConditionType() ?: 'eq'; - $fields[] = $filter->getField(); - $conditions[] = [$condition => $filter->getValue()]; - } - - if ($fields) { - $collection->addFieldToFilter($fields, $conditions); + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessorComposite' + ); } + return $this->collectionProcessor; } } diff --git a/app/code/Magento/Cms/Model/PageRepository.php b/app/code/Magento/Cms/Model/PageRepository.php index cce61f343a8..76f0de8dd86 100644 --- a/app/code/Magento/Cms/Model/PageRepository.php +++ b/app/code/Magento/Cms/Model/PageRepository.php @@ -8,7 +8,7 @@ namespace Magento\Cms\Model; use Magento\Cms\Api\Data; use Magento\Cms\Api\PageRepositoryInterface; use Magento\Framework\Api\DataObjectHelper; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\CouldNotDeleteException; use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\NoSuchEntityException; @@ -63,6 +63,11 @@ class PageRepository implements PageRepositoryInterface */ private $storeManager; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param ResourcePage $resource * @param PageFactory $pageFactory @@ -72,6 +77,7 @@ class PageRepository implements PageRepositoryInterface * @param DataObjectHelper $dataObjectHelper * @param DataObjectProcessor $dataObjectProcessor * @param StoreManagerInterface $storeManager + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( ResourcePage $resource, @@ -81,7 +87,8 @@ class PageRepository implements PageRepositoryInterface Data\PageSearchResultsInterfaceFactory $searchResultsFactory, DataObjectHelper $dataObjectHelper, DataObjectProcessor $dataObjectProcessor, - StoreManagerInterface $storeManager + StoreManagerInterface $storeManager, + CollectionProcessorInterface $collectionProcessor = null ) { $this->resource = $resource; $this->pageFactory = $pageFactory; @@ -91,6 +98,7 @@ class PageRepository implements PageRepositoryInterface $this->dataPageFactory = $dataPageFactory; $this->dataObjectProcessor = $dataObjectProcessor; $this->storeManager = $storeManager; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -144,28 +152,11 @@ class PageRepository implements PageRepositoryInterface */ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $criteria) { - $searchResults = $this->searchResultsFactory->create(); - $searchResults->setSearchCriteria($criteria); - /** @var \Magento\Cms\Model\ResourceModel\Page\Collection $collection */ $collection = $this->pageCollectionFactory->create(); - foreach ($criteria->getFilterGroups() as $filterGroup) { - $this->addFilterGroupToCollection($filterGroup, $collection); - } - $searchResults->setTotalCount($collection->getSize()); - $sortOrders = $criteria->getSortOrders(); - if ($sortOrders) { - /** @var SortOrder $sortOrder */ - foreach ($sortOrders as $sortOrder) { - $collection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - } - $collection->setCurPage($criteria->getCurrentPage()); - $collection->setPageSize($criteria->getPageSize()); + $this->collectionProcessor->process($criteria, $collection); + $pages = []; /** @var Page $pageModel */ foreach ($collection as $pageModel) { @@ -180,7 +171,12 @@ class PageRepository implements PageRepositoryInterface \Magento\Cms\Api\Data\PageInterface::class ); } + + /** @var Data\PageSearchResultsInterface $searchResults */ + $searchResults = $this->searchResultsFactory->create(); + $searchResults->setSearchCriteria($criteria); $searchResults->setItems($pages); + $searchResults->setTotalCount($collection->getSize()); return $searchResults; } @@ -218,31 +214,18 @@ class PageRepository implements PageRepositoryInterface } /** - * Helper function that adds a FilterGroup to the collection. + * Retrieve collection processor * - * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup - * @param \Magento\Cms\Model\ResourceModel\Page\Collection $collection - * @return void - * @throws \Magento\Framework\Exception\InputException - */ - private function addFilterGroupToCollection( - \Magento\Framework\Api\Search\FilterGroup $filterGroup, - \Magento\Cms\Model\ResourceModel\Page\Collection $collection - ) { - $fields = []; - $conditions = []; - foreach ($filterGroup->getFilters() as $filter) { - if ($filter->getField() === 'store_id') { - $collection->addStoreFilter($filter->getValue(), false); - continue; - } - $condition = $filter->getConditionType() ?: 'eq'; - $fields[] = $filter->getField(); - $conditions[] = [$condition => $filter->getValue()]; - } - - if ($fields) { - $collection->addFieldToFilter($fields, $conditions); + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessorComposite' + ); } + return $this->collectionProcessor; } } diff --git a/app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilterTest.php b/app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilterTest.php new file mode 100644 index 00000000000..8f96abdcbab --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/BlockStoreFilterTest.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\BlockStoreFilter; + +class BlockStoreFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var BlockStoreFilter + */ + private $filter; + + protected function setUp() + { + $this->filter = new BlockStoreFilter(); + } + + public function testApply() + { + $filterValue = 'filter_value'; + + $filterMock = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn($filterValue); + + $collectionMock = $this->getMockBuilder(\Magento\Cms\Model\ResourceModel\Block\Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $collectionMock->expects($this->once()) + ->method('addStoreFilter') + ->with($filterValue, false) + ->willReturnSelf(); + + $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilterTest.php b/app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilterTest.php new file mode 100644 index 00000000000..4d4a6ff4efa --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/PageStoreFilterTest.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Cms\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\PageStoreFilter; + +class PageStoreFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var PageStoreFilter + */ + private $filter; + + protected function setUp() + { + $this->filter = new PageStoreFilter(); + } + + public function testApply() + { + $filterValue = 'filter_value'; + + $filterMock = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn($filterValue); + + $collectionMock = $this->getMockBuilder(\Magento\Cms\Model\ResourceModel\Page\Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $collectionMock->expects($this->once()) + ->method('addStoreFilter') + ->with($filterValue, false) + ->willReturnSelf(); + + $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php b/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php index c6f7eb75927..3144d38a96c 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php @@ -6,7 +6,7 @@ namespace Magento\Cms\Test\Unit\Model; use Magento\Cms\Model\BlockRepository; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * Test for Magento\Cms\Model\BlockRepository @@ -60,6 +60,11 @@ class BlockRepositoryTest extends \PHPUnit_Framework_TestCase */ private $storeManager; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * Initialize repository */ @@ -131,6 +136,9 @@ class BlockRepositoryTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->collectionProcessor = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMockForAbstractClass(); + $this->repository = new BlockRepository( $this->blockResource, $blockFactory, @@ -139,7 +147,8 @@ class BlockRepositoryTest extends \PHPUnit_Framework_TestCase $blockSearchResultFactory, $this->dataHelper, $this->dataObjectProcessor, - $this->storeManager + $this->storeManager, + $this->collectionProcessor ); } @@ -229,54 +238,42 @@ class BlockRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetList() { - $field = 'name'; - $value = 'magento'; - $condition = 'eq'; $total = 10; - $currentPage = 3; - $pageSize = 2; - $sortField = 'id'; - - $criteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaInterface::class)->getMock(); - $filterGroup = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class)->getMock(); - $filter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class)->getMock(); - $storeFilter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class)->getMock(); - $sortOrder = $this->getMockBuilder(\Magento\Framework\Api\SortOrder::class)->getMock(); - - $criteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]); - $criteria->expects($this->once())->method('getSortOrders')->willReturn([$sortOrder]); - $criteria->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $criteria->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $filterGroup->expects($this->once())->method('getFilters')->willReturn([$storeFilter, $filter]); - $filter->expects($this->once())->method('getConditionType')->willReturn($condition); - $filter->expects($this->any())->method('getField')->willReturn($field); - $filter->expects($this->once())->method('getValue')->willReturn($value); - $storeFilter->expects($this->any())->method('getField')->willReturn('store_id'); - $storeFilter->expects($this->once())->method('getValue')->willReturn(1); - $sortOrder->expects($this->once())->method('getField')->willReturn($sortField); - $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_DESC); /** @var \Magento\Framework\Api\SearchCriteriaInterface $criteria */ + $criteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaInterface::class)->getMock(); $this->collection->addItem($this->block); + $this->collection->expects($this->once()) + ->method('getSize') + ->willReturn($total); + + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($criteria, $this->collection) + ->willReturnSelf(); + $this->blockSearchResult->expects($this->once()) ->method('setSearchCriteria') ->with($criteria) ->willReturnSelf(); - $this->collection->expects($this->once()) - ->method('addFieldToFilter') - ->with([$field], [[$condition => $value]]) + $this->blockSearchResult->expects($this->once()) + ->method('setTotalCount') + ->with($total) + ->willReturnSelf(); + $this->blockSearchResult->expects($this->once()) + ->method('setItems') + ->with(['someData']) ->willReturnSelf(); - $this->blockSearchResult->expects($this->once())->method('setTotalCount')->with($total)->willReturnSelf(); - $this->collection->expects($this->once())->method('getSize')->willReturn($total); - $this->collection->expects($this->once())->method('setCurPage')->with($currentPage)->willReturnSelf(); - $this->collection->expects($this->once())->method('setPageSize')->with($pageSize)->willReturnSelf(); - $this->collection->expects($this->once())->method('addOrder')->with($sortField, 'DESC')->willReturnSelf(); - $this->block->expects($this->once())->method('getData')->willReturn(['data']); - $this->blockSearchResult->expects($this->once())->method('setItems')->with(['someData'])->willReturnSelf(); + + $this->block->expects($this->once()) + ->method('getData') + ->willReturn(['data']); + $this->dataHelper->expects($this->once()) ->method('populateWithArray') ->with($this->blockData, ['data'], \Magento\Cms\Api\Data\BlockInterface::class); + $this->dataObjectProcessor->expects($this->once()) ->method('buildOutputDataArray') ->with($this->blockData, \Magento\Cms\Api\Data\BlockInterface::class) diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php index 5a16a8c972d..d11126881ba 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php @@ -6,7 +6,7 @@ namespace Magento\Cms\Test\Unit\Model; use Magento\Cms\Model\PageRepository; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * Test for Magento\Cms\Model\PageRepository @@ -60,6 +60,11 @@ class PageRepositoryTest extends \PHPUnit_Framework_TestCase */ private $storeManager; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * Initialize repository */ @@ -103,7 +108,7 @@ class PageRepositoryTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->collection = $this->getMockBuilder(\Magento\Cms\Model\ResourceModel\Page\Collection::class) ->disableOriginalConstructor() - ->setMethods(['addFieldToFilter', 'getSize', 'setCurPage', 'setPageSize', 'load', 'addOrder']) + ->setMethods(['getSize', 'setCurPage', 'setPageSize', 'load', 'addOrder']) ->getMock(); $pageFactory->expects($this->any()) @@ -129,6 +134,9 @@ class PageRepositoryTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->collectionProcessor = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMockForAbstractClass(); + $this->repository = new PageRepository( $this->pageResource, $pageFactory, @@ -137,7 +145,8 @@ class PageRepositoryTest extends \PHPUnit_Framework_TestCase $pageSearchResultFactory, $this->dataHelper, $this->dataObjectProcessor, - $this->storeManager + $this->storeManager, + $this->collectionProcessor ); } @@ -227,51 +236,42 @@ class PageRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetList() { - $field = 'name'; - $value = 'magento'; - $condition = 'eq'; $total = 10; - $currentPage = 3; - $pageSize = 2; - $sortField = 'id'; - - $criteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaInterface::class)->getMock(); - $filterGroup = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class)->getMock(); - $filter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class)->getMock(); - $storeFilter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class)->getMock(); - $sortOrder = $this->getMockBuilder(\Magento\Framework\Api\SortOrder::class)->getMock(); - - $criteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]); - $criteria->expects($this->once())->method('getSortOrders')->willReturn([$sortOrder]); - $criteria->expects($this->once())->method('getCurrentPage')->willReturn($currentPage); - $criteria->expects($this->once())->method('getPageSize')->willReturn($pageSize); - $filterGroup->expects($this->once())->method('getFilters')->willReturn([$storeFilter, $filter]); - $filter->expects($this->once())->method('getConditionType')->willReturn($condition); - $filter->expects($this->any())->method('getField')->willReturn($field); - $filter->expects($this->once())->method('getValue')->willReturn($value); - $storeFilter->expects($this->any())->method('getField')->willReturn('store_id'); - $storeFilter->expects($this->once())->method('getValue')->willReturn(1); - $sortOrder->expects($this->once())->method('getField')->willReturn($sortField); - $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_DESC); /** @var \Magento\Framework\Api\SearchCriteriaInterface $criteria */ + $criteria = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaInterface::class)->getMock(); $this->collection->addItem($this->page); - $this->pageSearchResult->expects($this->once())->method('setSearchCriteria')->with($criteria)->willReturnSelf(); $this->collection->expects($this->once()) - ->method('addFieldToFilter') - ->with([$field], [[$condition => $value]]) + ->method('getSize') + ->willReturn($total); + + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($criteria, $this->collection) ->willReturnSelf(); - $this->pageSearchResult->expects($this->once())->method('setTotalCount')->with($total)->willReturnSelf(); - $this->collection->expects($this->once())->method('getSize')->willReturn($total); - $this->collection->expects($this->once())->method('setCurPage')->with($currentPage)->willReturnSelf(); - $this->collection->expects($this->once())->method('setPageSize')->with($pageSize)->willReturnSelf(); - $this->collection->expects($this->once())->method('addOrder')->with($sortField, 'DESC')->willReturnSelf(); - $this->page->expects($this->once())->method('getData')->willReturn(['data']); - $this->pageSearchResult->expects($this->once())->method('setItems')->with(['someData'])->willReturnSelf(); + + $this->pageSearchResult->expects($this->once()) + ->method('setSearchCriteria') + ->with($criteria) + ->willReturnSelf(); + $this->pageSearchResult->expects($this->once()) + ->method('setTotalCount') + ->with($total) + ->willReturnSelf(); + $this->pageSearchResult->expects($this->once()) + ->method('setItems') + ->with(['someData']) + ->willReturnSelf(); + + $this->page->expects($this->once()) + ->method('getData') + ->willReturn(['data']); + $this->dataHelper->expects($this->once()) ->method('populateWithArray') ->with($this->pageData, ['data'], \Magento\Cms\Api\Data\PageInterface::class); + $this->dataObjectProcessor->expects($this->once()) ->method('buildOutputDataArray') ->with($this->pageData, \Magento\Cms\Api\Data\PageInterface::class) diff --git a/app/code/Magento/Cms/etc/di.xml b/app/code/Magento/Cms/etc/di.xml index a287d89398c..a49136c2f1f 100644 --- a/app/code/Magento/Cms/etc/di.xml +++ b/app/code/Magento/Cms/etc/di.xml @@ -146,4 +146,46 @@ </argument> </arguments> </type> + <virtualType name="Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\PageFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="store_id" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\PageStoreFilter</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\PageFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Cms\Model\PageRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessorComposite</argument> + </arguments> + </type> + <virtualType name="Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\BlockFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="store_id" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\BlockStoreFilter</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\BlockFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Cms\Model\BlockRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessorComposite</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php b/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php index 2c30425f337..eb477d6b311 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php @@ -11,8 +11,8 @@ use Magento\Customer\Model\Address as CustomerAddressModel; use Magento\Customer\Model\Customer as CustomerModel; use Magento\Customer\Model\ResourceModel\Address\Collection; use Magento\Framework\Api\Search\FilterGroup; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; -use Magento\Framework\Api\SortOrder; use Magento\Framework\Exception\InputException; /** @@ -62,6 +62,11 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf */ protected $extensionAttributesJoinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param \Magento\Customer\Model\AddressFactory $addressFactory * @param \Magento\Customer\Model\AddressRegistry $addressRegistry @@ -71,6 +76,7 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf * @param \Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory $addressSearchResultsFactory * @param \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressCollectionFactory * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + * @param CollectionProcessorInterface $collectionProcessor */ public function __construct( \Magento\Customer\Model\AddressFactory $addressFactory, @@ -80,7 +86,8 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf \Magento\Directory\Helper\Data $directoryData, \Magento\Customer\Api\Data\AddressSearchResultsInterfaceFactory $addressSearchResultsFactory, \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressCollectionFactory, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $extensionAttributesJoinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->addressFactory = $addressFactory; $this->addressRegistry = $addressRegistry; @@ -90,6 +97,7 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf $this->addressSearchResultsFactory = $addressSearchResultsFactory; $this->addressCollectionFactory = $addressCollectionFactory; $this->extensionAttributesJoinProcessor = $extensionAttributesJoinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -164,29 +172,14 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf */ public function getList(SearchCriteriaInterface $searchCriteria) { - $searchResults = $this->addressSearchResultsFactory->create(); - /** @var Collection $collection */ $collection = $this->addressCollectionFactory->create(); $this->extensionAttributesJoinProcessor->process( $collection, \Magento\Customer\Api\Data\AddressInterface::class ); - // Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $collection); - } - $searchResults->setTotalCount($collection->getSize()); - /** @var SortOrder $sortOrder */ - foreach ((array)$searchCriteria->getSortOrders() as $sortOrder) { - $field = $sortOrder->getField(); - $collection->addOrder( - $field, - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + + $this->collectionProcessor->process($searchCriteria, $collection); /** @var \Magento\Customer\Api\Data\AddressInterface[] $addresses */ $addresses = []; @@ -194,14 +187,19 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf foreach ($collection->getItems() as $address) { $addresses[] = $this->getById($address->getId()); } + + /** @var \Magento\Customer\Api\Data\AddressSearchResultsInterface $searchResults */ + $searchResults = $this->addressSearchResultsFactory->create(); $searchResults->setItems($addresses); $searchResults->setSearchCriteria($searchCriteria); + $searchResults->setTotalCount($collection->getSize()); return $searchResults; } /** * Helper function that adds a FilterGroup to the collection. * + * @deprecated * @param FilterGroup $filterGroup * @param Collection $collection * @return void @@ -320,4 +318,20 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf } return $exception; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php index a6ab66c6e25..39845e576ab 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ namespace Magento\Customer\Test\Unit\Model\ResourceModel; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -65,6 +66,11 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $repository; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + protected function setUp() { $this->addressFactory = $this->getMock( @@ -130,6 +136,9 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase false ); + $this->collectionProcessor = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMockForAbstractClass(); + $this->repository = new \Magento\Customer\Model\ResourceModel\AddressRepository( $this->addressFactory, $this->addressRegistry, @@ -138,7 +147,8 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase $this->directoryData, $this->addressSearchResultsFactory, $this->addressCollectionFactory, - $this->extensionAttributesJoinProcessor + $this->extensionAttributesJoinProcessor, + $this->collectionProcessor ); } @@ -490,8 +500,6 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { - $filterGroup = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filter = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); $collection = $this->getMock( \Magento\Customer\Model\ResourceModel\Address\Collection::class, [], @@ -516,43 +524,16 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase $this->extensionAttributesJoinProcessor->expects($this->once()) ->method('process') ->with($collection, \Magento\Customer\Api\Data\AddressInterface::class); - $searchCriteria->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroup]); - $filterGroup->expects($this->once())->method('getFilters')->willReturn([$filter]); - $filter->expects($this->once())->method('getConditionType')->willReturn(false); - $filter->expects($this->once())->method('getField')->willReturn('Field'); - $filter->expects($this->atLeastOnce())->method('getValue')->willReturn('Value'); - $collection->expects($this->once()) - ->method('addFieldToFilter') - ->with([['attribute' => 'Field', 'eq' => 'Value']], [['eq' => 'Value']]); + + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteria, $collection) + ->willReturnSelf(); + $collection->expects($this->once())->method('getSize')->willReturn(23); $searchResults->expects($this->once()) ->method('setTotalCount') ->with(23); - $sortOrder = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false); - $searchCriteria->expects($this->once()) - ->method('getSortOrders') - ->willReturn([$sortOrder]); - $sortOrder->expects($this->once()) - ->method('getField') - ->willReturn('Field'); - $sortOrder->expects($this->once()) - ->method('getDirection') - ->willReturn(\Magento\Framework\Api\SortOrder::SORT_ASC); - $collection->expects($this->once()) - ->method('addOrder') - ->with('Field', 'ASC'); - $searchCriteria->expects($this->once()) - ->method('getCurrentPage') - ->willReturn(1); - $collection->expects($this->once()) - ->method('setCurPage') - ->with(1); - $searchCriteria->expects($this->once()) - ->method('getPageSize') - ->willReturn(10); - $collection->expects($this->once()) - ->method('setPageSize') - ->with(10); $collection->expects($this->once()) ->method('getItems') ->willReturn([$this->address]); diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 38f7d7a0e26..bb384d7f282 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -355,4 +355,9 @@ <argument name="collectionProcessor" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite</argument> </arguments> </type> + <type name="Magento\Customer\Model\ResourceModel\AddressRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php new file mode 100644 index 00000000000..a5de394668b --- /dev/null +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class AttributeGroupAttributeSetIdFilter implements CustomFilterInterface +{ + /** + * Apply attribute set ID filter to collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + if ($filter->getField() == 'attribute_set_id') { + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\Collection $collection */ + $collection->setAttributeSetFilter($filter->getValue()); + return true; + } + return false; + } +} diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php new file mode 100644 index 00000000000..68e07c61809 --- /dev/null +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class AttributeGroupCodeFilter implements CustomFilterInterface +{ + /** + * Apply attribute group code filter to collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + if ($filter->getField() == 'attribute_group_code') { + $collection->addFilter('attribute_group_code', $filter->getValue()); + return true; + } + return false; + } +} diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php new file mode 100644 index 00000000000..72c2f8f08c2 --- /dev/null +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Eav\Api\Data\AttributeInterface; +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class AttributeIdFilter implements CustomFilterInterface +{ + /** + * Apply attribute ID filter to collection + * + * Prevent ambiguity during filtration + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + if ($filter->getField() == AttributeInterface::ATTRIBUTE_ID) { + $conditionType = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; + $collection->addFieldToFilter( + 'main_table.' . $filter->getField(), + [$conditionType => $filter->getValue()] + ); + return true; + } + return false; + } +} diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php new file mode 100644 index 00000000000..7c0cb795746 --- /dev/null +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php @@ -0,0 +1,47 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Eav\Model\Config; +use Magento\Framework\Api\Filter; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; +use Magento\Framework\Data\Collection\AbstractDb; + +class AttributeSetEntityTypeCodeFilter implements CustomFilterInterface +{ + /** + * @var Config + */ + private $eavConfig; + + /** + * @param Config $eavConfig + */ + public function __construct( + Config $eavConfig + ) { + $this->eavConfig = $eavConfig; + } + + /** + * Apply entity type code filter to collection + * + * @param Filter $filter + * @param AbstractDb $collection + * @return bool + */ + public function apply(Filter $filter, AbstractDb $collection) + { + if ($filter->getField() == 'entity_type_code') { + $entityTypeCode = $filter->getValue(); + $entityType = $this->eavConfig->getEntityType($entityTypeCode); + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $collection */ + $collection->setEntityTypeFilter($entityType->getId()); + return true; + } + return false; + } +} diff --git a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php index db99854c719..37d22c1d0fc 100644 --- a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php +++ b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php @@ -6,6 +6,7 @@ */ namespace Magento\Eav\Model\Attribute; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; @@ -42,6 +43,11 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf */ protected $joinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group $groupResource * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory $groupListFactory @@ -49,6 +55,7 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf * @param \Magento\Eav\Api\AttributeSetRepositoryInterface $setRepository * @param \Magento\Eav\Api\Data\AttributeGroupSearchResultsInterfaceFactory $searchResultsFactory * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + * @param CollectionProcessorInterface $collectionProcessor * @codeCoverageIgnore */ public function __construct( @@ -57,7 +64,8 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf \Magento\Eav\Model\Entity\Attribute\GroupFactory $groupFactory, \Magento\Eav\Api\AttributeSetRepositoryInterface $setRepository, \Magento\Eav\Api\Data\AttributeGroupSearchResultsInterfaceFactory $searchResultsFactory, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->groupResource = $groupResource; $this->groupListFactory = $groupListFactory; @@ -65,6 +73,7 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf $this->setRepository = $setRepository; $this->searchResultsFactory = $searchResultsFactory; $this->joinProcessor = $joinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -116,15 +125,13 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf throw NoSuchEntityException::singleField('attributeSetId', $attributeSetId); } + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\Collection $collection */ $collection = $this->groupListFactory->create(); $this->joinProcessor->process($collection); - $collection->setAttributeSetFilter($attributeSetId); - $collection->setSortOrder(); - if ($attributeGroupCode = $this->retrieveAttributeGroupCodeFromSearchCriteria($searchCriteria)) { - $collection->addFilter('attribute_group_code', $attributeGroupCode); - } + $this->collectionProcessor->process($searchCriteria, $collection); + /** @var \Magento\Eav\Api\Data\AttributeGroupSearchResultsInterface $searchResult */ $searchResult = $this->searchResultsFactory->create(); $searchResult->setSearchCriteria($searchCriteria); $searchResult->setItems($collection->getItems()); @@ -196,6 +203,7 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf /** * Retrieve attribute group code * + * @deprecated * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria * @return null|string */ @@ -211,4 +219,20 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf } return null; } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Eav/Model/AttributeRepository.php b/app/code/Magento/Eav/Model/AttributeRepository.php index 53b90c939ae..b108c20e64b 100644 --- a/app/code/Magento/Eav/Model/AttributeRepository.php +++ b/app/code/Magento/Eav/Model/AttributeRepository.php @@ -7,7 +7,7 @@ namespace Magento\Eav\Model; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection; -use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; @@ -47,6 +47,11 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa */ protected $joinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param Config $eavConfig * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute $eavResource @@ -54,6 +59,7 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa * @param \Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory $searchResultsFactory * @param Entity\AttributeFactory $attributeFactory * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + * @param CollectionProcessorInterface $collectionProcessor * @codeCoverageIgnore */ public function __construct( @@ -62,7 +68,8 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa \Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory $attributeCollectionFactory, \Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory $searchResultsFactory, \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->eavConfig = $eavConfig; $this->eavResource = $eavResource; @@ -70,6 +77,7 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa $this->searchResultsFactory = $searchResultsFactory; $this->attributeFactory = $attributeFactory; $this->joinProcessor = $joinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -118,34 +126,23 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa [] ); } - //Add filters from root filter group to the collection - foreach ($searchCriteria->getFilterGroups() as $group) { - $this->addFilterGroupToCollection($group, $attributeCollection); - } - /** @var SortOrder $sortOrder */ - foreach ((array)$searchCriteria->getSortOrders() as $sortOrder) { - $attributeCollection->addOrder( - $sortOrder->getField(), - ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC' - ); - } - $totalCount = $attributeCollection->getSize(); + $this->collectionProcessor->process($searchCriteria, $attributeCollection); // Group attributes by id to prevent duplicates with different attribute sets $attributeCollection->addAttributeGrouping(); - $attributeCollection->setCurPage($searchCriteria->getCurrentPage()); - $attributeCollection->setPageSize($searchCriteria->getPageSize()); $attributes = []; /** @var \Magento\Eav\Api\Data\AttributeInterface $attribute */ foreach ($attributeCollection as $attribute) { $attributes[] = $this->get($entityTypeCode, $attribute->getAttributeCode()); } + + /** @var \Magento\Eav\Api\Data\AttributeSearchResultsInterface $searchResults */ $searchResults = $this->searchResultsFactory->create(); $searchResults->setSearchCriteria($searchCriteria); $searchResults->setItems($attributes); - $searchResults->setTotalCount($totalCount); + $searchResults->setTotalCount($attributeCollection->getSize()); return $searchResults; } @@ -197,6 +194,7 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa /** * Helper function that adds a FilterGroup to the collection. * + * @deprecated * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $collection * @return void @@ -219,4 +217,20 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa ); } } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Eav\Model\Api\SearchCriteria\AttributeCollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Eav/Model/AttributeSetRepository.php b/app/code/Magento/Eav/Model/AttributeSetRepository.php index 622bd0e49bc..4a5e239f6f1 100644 --- a/app/code/Magento/Eav/Model/AttributeSetRepository.php +++ b/app/code/Magento/Eav/Model/AttributeSetRepository.php @@ -12,6 +12,7 @@ use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet; use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set as AttributeSetResource; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\CouldNotDeleteException; use Magento\Framework\Exception\CouldNotSaveException; use Magento\Framework\Exception\NoSuchEntityException; @@ -51,6 +52,11 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface */ protected $joinProcessor; + /** + * @var CollectionProcessorInterface + */ + private $collectionProcessor; + /** * @param AttributeSetResource $attributeSetResource * @param AttributeSetFactory $attributeSetFactory @@ -58,6 +64,7 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface * @param Config $eavConfig * @param \Magento\Eav\Api\Data\AttributeSetSearchResultsInterfaceFactory $searchResultFactory * @param \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + * @param CollectionProcessorInterface $collectionProcessor * @codeCoverageIgnore */ public function __construct( @@ -66,7 +73,8 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface CollectionFactory $collectionFactory, EavConfig $eavConfig, \Magento\Eav\Api\Data\AttributeSetSearchResultsInterfaceFactory $searchResultFactory, - \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor + \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, + CollectionProcessorInterface $collectionProcessor = null ) { $this->attributeSetResource = $attributeSetResource; $this->attributeSetFactory = $attributeSetFactory; @@ -74,6 +82,7 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface $this->eavConfig = $eavConfig; $this->searchResultsFactory = $searchResultFactory; $this->joinProcessor = $joinProcessor; + $this->collectionProcessor = $collectionProcessor ?: $this->getCollectionProcessor(); } /** @@ -98,16 +107,9 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface $collection = $this->collectionFactory->create(); $this->joinProcessor->process($collection); - /** The only possible/meaningful search criteria for attribute set is entity type code */ - $entityTypeCode = $this->getEntityTypeCode($searchCriteria); - - if ($entityTypeCode !== null) { - $collection->setEntityTypeFilter($this->eavConfig->getEntityType($entityTypeCode)->getId()); - } - - $collection->setCurPage($searchCriteria->getCurrentPage()); - $collection->setPageSize($searchCriteria->getPageSize()); + $this->collectionProcessor->process($searchCriteria, $collection); + /** @var \Magento\Eav\Api\Data\AttributeSetSearchResultsInterface $searchResults */ $searchResults = $this->searchResultsFactory->create(); $searchResults->setSearchCriteria($searchCriteria); $searchResults->setItems($collection->getItems()); @@ -118,6 +120,7 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface /** * Retrieve entity type code from search criteria * + * @deprecated * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria * @return null|string */ @@ -170,4 +173,20 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface { return $this->delete($this->get($attributeSetId)); } + + /** + * Retrieve collection processor + * + * @deprecated + * @return CollectionProcessorInterface + */ + private function getCollectionProcessor() + { + if (!$this->collectionProcessor) { + $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( + 'Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessorComposite' + ); + } + return $this->collectionProcessor; + } } diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php new file mode 100644 index 00000000000..fdef7b46a0c --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeGroupCodeFilter; +use Magento\Framework\Api\Filter; +use Magento\Framework\Data\Collection\AbstractDb; + +class AttributeGroupCodeFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AttributeGroupCodeFilter + */ + private $filter; + + protected function setUp() + { + $this->filter = new AttributeGroupCodeFilter(); + } + + public function testApply() + { + $filterValue = 'filter_value'; + + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn('attribute_group_code'); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn($filterValue); + + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->setMethods(['addFilter']) + ->getMockForAbstractClass(); + $collectionMock->expects($this->once()) + ->method('addFilter') + ->with('attribute_group_code', $filterValue) + ->willReturnSelf(); + + $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); + } + + public function testApplyIdle() + { + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn(null); + + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php new file mode 100644 index 00000000000..6291ee629f5 --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php @@ -0,0 +1,69 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Eav\Api\Data\AttributeInterface; +use Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeIdFilter; +use Magento\Framework\Api\Filter; +use Magento\Framework\Data\Collection\AbstractDb; + +class AttributeIdFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AttributeIdFilter + */ + private $filter; + + protected function setUp() + { + $this->filter = new AttributeIdFilter(); + } + + public function testApply() + { + $filterValue = 'filter_value'; + + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->exactly(2)) + ->method('getField') + ->willReturn(AttributeInterface::ATTRIBUTE_ID); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn($filterValue); + $filterMock->expects($this->once()) + ->method('getConditionType') + ->willReturn(null); + + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->setMethods(['addFieldToFilter']) + ->getMockForAbstractClass(); + $collectionMock->expects($this->once()) + ->method('addFieldToFilter') + ->with('main_table.' . AttributeInterface::ATTRIBUTE_ID, ['eq' => $filterValue]) + ->willReturnSelf(); + + $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); + } + + public function testApplyIdle() + { + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn(null); + + $collectionMock = $this->getMockBuilder(AbstractDb::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php new file mode 100644 index 00000000000..f5170b3b090 --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php @@ -0,0 +1,88 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeSetEntityTypeCodeFilter; +use Magento\Eav\Model\Config; +use Magento\Eav\Model\Entity\Type; +use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection; +use Magento\Framework\Api\Filter; + +class EntityTypeCodeFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AttributeSetEntityTypeCodeFilter + */ + private $filter; + + /** + * @var Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + + protected function setUp() + { + $this->eavConfig = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->filter = new AttributeSetEntityTypeCodeFilter($this->eavConfig); + } + + public function testApply() + { + $filterValue = 'filter_value'; + $entityTypeId = 1; + + $entityTypeMock = $this->getMockBuilder(Type::class) + ->disableOriginalConstructor() + ->getMock(); + $entityTypeMock->expects($this->once()) + ->method('getId') + ->willReturn($entityTypeId); + + $this->eavConfig->expects($this->once()) + ->method('getEntityType') + ->with($filterValue) + ->willReturn($entityTypeMock); + + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn('entity_type_code'); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn($filterValue); + + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $collectionMock->expects($this->once()) + ->method('setEntityTypeFilter') + ->with($entityTypeId) + ->willReturnSelf(); + + $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); + } + + public function testApplyIdle() + { + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn(null); + + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php new file mode 100644 index 00000000000..c09b5716658 --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; + +use Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeGroupAttributeSetIdFilter; +use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\Collection; +use Magento\Framework\Api\Filter; + +class AttributeGroupAttributeSetIdFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AttributeGroupAttributeSetIdFilter + */ + private $filter; + + protected function setUp() + { + $this->filter = new AttributeGroupAttributeSetIdFilter(); + } + + public function testApply() + { + $filterValue = 'filter_value'; + + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn('attribute_set_id'); + $filterMock->expects($this->once()) + ->method('getValue') + ->willReturn($filterValue); + + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $collectionMock->expects($this->once()) + ->method('setAttributeSetFilter') + ->with($filterValue) + ->willReturnSelf(); + + $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); + } + + public function testApplyIdle() + { + $filterMock = $this->getMockBuilder(Filter::class) + ->disableOriginalConstructor() + ->getMock(); + $filterMock->expects($this->once()) + ->method('getField') + ->willReturn(null); + + $collectionMock = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); + } +} diff --git a/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php index 4a30ba9e1f1..76fc8f8b02a 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ namespace Magento\Eav\Test\Unit\Model\Attribute; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -40,6 +41,11 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase */ protected $groupListFactoryMock; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * SetUp method * @@ -77,6 +83,9 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase false ); + $this->collectionProcessor = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMockForAbstractClass(); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->model = $objectManager->getObject( \Magento\Eav\Model\Attribute\GroupRepository::class, @@ -85,7 +94,8 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase 'groupListFactory' => $this->groupListFactoryMock, 'groupFactory' => $this->groupFactoryMock, 'setRepository' => $this->setRepositoryMock, - 'searchResultsFactory' => $this->searchResultsFactoryMock + 'searchResultsFactory' => $this->searchResultsFactoryMock, + 'collectionProcessor' => $this->collectionProcessor ] ); } @@ -274,34 +284,50 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase public function testGetList() { $attributeSetId = 'filter'; - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $filterInterfaceMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $attributeSetMock = $this->getMock(\Magento\Eav\Api\Data\AttributeSetInterface::class); - $groupMock = $this->getMock(\Magento\Eav\Model\Entity\Attribute\Group::class, [], [], '', false); + + $filterInterfaceMock = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getField', + 'getValue', + ]) + ->getMock(); + $filterInterfaceMock->expects($this->once()) + ->method('getField') + ->willReturn('attribute_set_id'); + $filterInterfaceMock->expects($this->once()) + ->method('getValue') + ->willReturn($attributeSetId); + + $filterGroupMock = $this->getMockBuilder(\Magento\Framework\Api\Search\FilterGroup::class) + ->disableOriginalConstructor() + ->getMock(); + $filterGroupMock->expects($this->once()) + ->method('getFilters') + ->willReturn([$filterInterfaceMock]); + + $searchCriteriaMock = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $searchCriteriaMock->expects($this->once()) + ->method('getFilterGroups') + ->willReturn([$filterGroupMock]); + + $groupMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Group::class) + ->disableOriginalConstructor() + ->getMock(); $groupCollectionMock = $this->getMock( \Magento\Eav\Model\Entity\Collection\AbstractCollection::class, - ['setAttributeSetFilter', 'setSortOrder', 'getItems', 'getSize'], + ['getItems', 'getSize'], [], '', false ); $groupCollectionMock->expects($this->once())->method('getItems')->willReturn([$groupMock]); - $searchCriteriaMock->expects($this->exactly(2))->method('getFilterGroups')->willReturn([$filterGroupMock]); - - $filterGroupMock->expects($this->exactly(2))->method('getFilters')->willReturn([$filterInterfaceMock]); - $filterInterfaceMock->expects($this->exactly(2))->method('getField')->willReturn('attribute_set_id'); - $filterInterfaceMock->expects($this->once())->method('getValue')->willReturn($attributeSetId); - $this->setRepositoryMock->expects($this->once()) - ->method('get') - ->with($attributeSetId) - ->willReturn($attributeSetMock); $this->groupListFactoryMock->expects($this->once())->method('create')->willReturn($groupCollectionMock); - $groupCollectionMock->expects($this->once())->method('setAttributeSetFilter')->with($attributeSetId); - $groupCollectionMock->expects($this->once())->method('setSortOrder'); $groupCollectionMock->expects($this->once())->method('getSize')->willReturn(1); $searchResultsMock = $this->getMock( @@ -315,6 +341,12 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase $searchResultsMock->expects($this->once())->method('setItems')->with([$groupMock]); $searchResultsMock->expects($this->once())->method('setTotalCount')->with(1); $this->searchResultsFactoryMock->expects($this->once())->method('create')->willReturn($searchResultsMock); + + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $groupCollectionMock) + ->willReturnSelf(); + $this->assertEquals($searchResultsMock, $this->model->getList($searchCriteriaMock)); } diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php new file mode 100644 index 00000000000..cdb71a55b9c --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php @@ -0,0 +1,233 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Test\Unit\Model; + +use Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory; +use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory; +use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; + +class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + + /** + * @var \Magento\Eav\Model\ResourceModel\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavResource; + + /** + * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $attributeCollectionFactory; + + /** + * @var AttributeSearchResultsInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $searchResultsFactory; + + /** + * @var \Magento\Eav\Model\Entity\AttributeFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $attributeFactory; + + /** + * @var JoinProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $joinProcessor; + + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + + /** + * @var \Magento\Eav\Model\AttributeRepository + */ + private $model; + + protected function setUp() + { + $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->eavResource = $this->getMockBuilder(\Magento\Eav\Model\ResourceModel\Entity\Attribute::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attributeCollectionFactory = $this->getMockBuilder(CollectionFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->searchResultsFactory = $this->getMockBuilder(AttributeSearchResultsInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->attributeFactory = $this->getMockBuilder(\Magento\Eav\Model\Entity\AttributeFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->joinProcessor = $this->getMockBuilder(JoinProcessorInterface::class) + ->getMockForAbstractClass(); + + $this->collectionProcessor = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMockForAbstractClass(); + + $this->model = new \Magento\Eav\Model\AttributeRepository( + $this->eavConfig, + $this->eavResource, + $this->attributeCollectionFactory, + $this->searchResultsFactory, + $this->attributeFactory, + $this->joinProcessor, + $this->collectionProcessor + ); + } + + /** + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage entity_type_code is a required field. + */ + public function testGetListInputException() + { + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMockForAbstractClass(); + + $this->model->getList(null, $searchCriteriaMock); + } + + public function testGetList() + { + $entityTypeCode = 'entity_type_code'; + $eavEntityTypeTable = 'eav_entity_type_table'; + $eavEntityAttributeTable = 'eav_entity_attribute_table'; + $additionalTable = 'additional_table'; + $attributeCode = 'attribute_code'; + $attributeId = 1; + $collectionSize = 1; + + $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) + ->getMockForAbstractClass(); + + $attributeMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeInterface::class) + ->setMethods([ + 'getAttributeCode', + 'getAttributeId', + ]) + ->getMockForAbstractClass(); + $attributeMock->expects($this->once()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->once()) + ->method('getAttributeId') + ->willReturn($attributeId); + + $attributeCollectionMock = $this->getMockBuilder(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $attributeCollectionMock->expects($this->once()) + ->method('addFieldToFilter') + ->with('entity_type_code', ['eq' => $entityTypeCode]) + ->willReturnSelf(); + $attributeCollectionMock->expects($this->exactly(3)) + ->method('getTable') + ->willReturnMap([ + ['eav_entity_type', $eavEntityTypeTable], + ['eav_entity_attribute', $eavEntityAttributeTable], + [$additionalTable, $additionalTable], + ]); + $attributeCollectionMock->expects($this->exactly(2)) + ->method('join') + ->willReturnMap([ + [ + ['entity_type' => $eavEntityTypeTable], + 'main_table.entity_type_id = entity_type.entity_type_id', + [] + ], + [ + ['additional_table' => $additionalTable], + 'main_table.attribute_id = additional_table.attribute_id', + [] + ] + ]); + $attributeCollectionMock->expects($this->once()) + ->method('joinLeft') + ->with( + ['eav_entity_attribute' => $eavEntityAttributeTable], + 'main_table.attribute_id = eav_entity_attribute.attribute_id', + [] + ) + ->willReturnSelf(); + $attributeCollectionMock->expects($this->once()) + ->method('addAttributeGrouping') + ->willReturnSelf(); + $attributeCollectionMock->expects($this->once()) + ->method('getIterator') + ->willReturn(new \ArrayIterator([$attributeMock])); + $attributeCollectionMock->expects($this->once()) + ->method('getSize') + ->willReturn($collectionSize); + + $this->attributeCollectionFactory->expects($this->once()) + ->method('create') + ->willReturn($attributeCollectionMock); + + $this->joinProcessor->expects($this->once()) + ->method('process') + ->with($attributeCollectionMock) + ->willReturnSelf(); + + $entityTypeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Type::class) + ->disableOriginalConstructor() + ->setMethods(['getAdditionalAttributeTable']) + ->getMock(); + $entityTypeMock->expects($this->once()) + ->method('getAdditionalAttributeTable') + ->willReturn($additionalTable); + + $this->eavConfig->expects($this->once()) + ->method('getEntityType') + ->with($entityTypeCode) + ->willReturn($entityTypeMock); + $this->eavConfig->expects($this->once()) + ->method('getAttribute') + ->with($entityTypeCode, $attributeCode) + ->willReturn($attributeMock); + + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $attributeCollectionMock) + ->willReturnSelf(); + + $searchResultsMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSearchResultsInterface::class) + ->getMockForAbstractClass(); + $searchResultsMock->expects($this->once()) + ->method('setSearchCriteria') + ->with($searchCriteriaMock) + ->willReturnSelf(); + $searchResultsMock->expects($this->once()) + ->method('setItems') + ->with([$attributeMock]) + ->willReturnSelf(); + $searchResultsMock->expects($this->once()) + ->method('setTotalCount') + ->with($collectionSize) + ->willReturnSelf(); + + $this->searchResultsFactory->expects($this->once()) + ->method('create') + ->willReturn($searchResultsMock); + + $this->assertEquals($searchResultsMock, $this->model->getList($entityTypeCode, $searchCriteriaMock)); + } +} diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php index 244c620fac8..b2d20926161 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeSetRepositoryTest.php @@ -6,6 +6,7 @@ namespace Magento\Eav\Test\Unit\Model; use Magento\Eav\Model\AttributeSetRepository; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** * @SuppressWarnings(PHPMD.LongVariable) @@ -48,6 +49,11 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase */ private $extensionAttributesJoinProcessorMock; + /** + * @var CollectionProcessorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionProcessor; + /** * @return void */ @@ -89,13 +95,18 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase '', false ); + + $this->collectionProcessor = $this->getMockBuilder(CollectionProcessorInterface::class) + ->getMockForAbstractClass(); + $this->model = new \Magento\Eav\Model\AttributeSetRepository( $this->resourceMock, $this->setFactoryMock, $this->collectionFactoryMock, $this->eavConfigMock, $this->resultFactoryMock, - $this->extensionAttributesJoinProcessorMock + $this->extensionAttributesJoinProcessorMock, + $this->collectionProcessor ); } @@ -207,58 +218,30 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetList() { - $entityTypeCode = 'entity_type_code_value'; - $entityTypeId = 41; - - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - - $filterGroupMock = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false); - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([$filterGroupMock]); - - $filterMock = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false); - $filterGroupMock->expects($this->once())->method('getFilters')->willReturn([$filterMock]); - - $filterMock->expects($this->once())->method('getField')->willReturn('entity_type_code'); - $filterMock->expects($this->once())->method('getValue')->willReturn($entityTypeCode); - - $collectionMock = $this->getMock( - \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class, - ['setEntityTypeFilter', 'setCurPage', 'setPageSize', 'getItems', 'getSize'], - [], - '', - false - ); + $attributeSetMock = $this->getMock(\Magento\Eav\Model\Entity\Attribute\Set::class, [], [], '', false); - $entityTypeMock = $this->getMock(\Magento\Eav\Model\Entity\Type::class, [], [], '', false); - $entityTypeMock->expects($this->once())->method('getId')->willReturn($entityTypeId); - $this->eavConfigMock->expects($this->once()) - ->method('getEntityType') - ->with($entityTypeCode) - ->willReturn($entityTypeMock); + $collectionMock = $this->getMockBuilder(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getItems', + 'getSize', + ]) + ->getMock(); - $this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock); $collectionMock->expects($this->once()) - ->method('setEntityTypeFilter') - ->with($entityTypeId) - ->willReturnSelf(); + ->method('getItems') + ->willReturn([$attributeSetMock]); + $collectionMock->expects($this->once()) + ->method('getSize') + ->willReturn(1); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn(1); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn(10); + $this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock); - $collectionMock->expects($this->once())->method('setCurPage')->with(1)->willReturnSelf(); - $collectionMock->expects($this->once())->method('setPageSize')->with(10)->willReturnSelf(); + $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $attributeSetMock = $this->getMock(\Magento\Eav\Model\Entity\Attribute\Set::class, [], [], '', false); - $collectionMock->expects($this->once())->method('getItems')->willReturn([$attributeSetMock]); - $collectionMock->expects($this->once())->method('getSize')->willReturn(1); + $resultMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSetSearchResultsInterface::class) + ->getMockForAbstractClass(); - $resultMock = $this->getMock( - \Magento\Eav\Api\Data\AttributeSetSearchResultsInterface::class, - [], - [], - '', - false - ); $resultMock->expects($this->once()) ->method('setSearchCriteria') ->with($searchCriteriaMock) @@ -267,9 +250,19 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase ->method('setItems') ->with([$attributeSetMock]) ->willReturnSelf(); - $resultMock->expects($this->once())->method('setTotalCount')->with(1)->willReturnSelf(); + $resultMock->expects($this->once()) + ->method('setTotalCount') + ->with(1) + ->willReturnSelf(); - $this->resultFactoryMock->expects($this->once())->method('create')->willReturn($resultMock); + $this->resultFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($resultMock); + + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock) + ->willReturnSelf(); $this->model->getList($searchCriteriaMock); } @@ -279,36 +272,32 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase */ public function testGetListIfEntityTypeCodeIsNull() { - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $searchCriteriaMock->expects($this->once())->method('getFilterGroups')->willReturn([]); + $attributeSetMock = $this->getMock(\Magento\Eav\Model\Entity\Attribute\Set::class, [], [], '', false); - $collectionMock = $this->getMock( - \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class, - ['setCurPage', 'setPageSize', 'getItems', 'getSize'], - [], - '', - false - ); + $collectionMock = $this->getMockBuilder(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getItems', + 'getSize', + ]) + ->getMock(); - $this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock); + $collectionMock->expects($this->once()) + ->method('getItems') + ->willReturn([$attributeSetMock]); + $collectionMock->expects($this->once()) + ->method('getSize') + ->willReturn(1); - $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn(1); - $searchCriteriaMock->expects($this->once())->method('getPageSize')->willReturn(10); + $this->collectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($collectionMock); - $collectionMock->expects($this->once())->method('setCurPage')->with(1)->willReturnSelf(); - $collectionMock->expects($this->once())->method('setPageSize')->with(10)->willReturnSelf(); + $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class); - $attributeSetMock = $this->getMock(\Magento\Eav\Model\Entity\Attribute\Set::class, [], [], '', false); - $collectionMock->expects($this->once())->method('getItems')->willReturn([$attributeSetMock]); - $collectionMock->expects($this->once())->method('getSize')->willReturn(1); + $resultMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSetSearchResultsInterface::class) + ->getMockForAbstractClass(); - $resultMock = $this->getMock( - \Magento\Eav\Api\Data\AttributeSetSearchResultsInterface::class, - [], - [], - '', - false - ); $resultMock->expects($this->once()) ->method('setSearchCriteria') ->with($searchCriteriaMock) @@ -317,9 +306,19 @@ class AttributeSetRepositoryTest extends \PHPUnit_Framework_TestCase ->method('setItems') ->with([$attributeSetMock]) ->willReturnSelf(); - $resultMock->expects($this->once())->method('setTotalCount')->with(1)->willReturnSelf(); + $resultMock->expects($this->once()) + ->method('setTotalCount') + ->with(1) + ->willReturnSelf(); + + $this->resultFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($resultMock); - $this->resultFactoryMock->expects($this->once())->method('create')->willReturn($resultMock); + $this->collectionProcessor->expects($this->once()) + ->method('process') + ->with($searchCriteriaMock, $collectionMock) + ->willReturnSelf(); $this->model->getList($searchCriteriaMock); } diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index 4dd117bbc29..7ac08c4aee6 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -91,5 +91,76 @@ </argument> </arguments> </virtualType> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="attribute_id" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeIdFilter</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Eav\Model\AttributeRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeCollectionProcessorComposite</argument> + </arguments> + </type> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeSetFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="entity_type_code" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeSetEntityTypeCodeFilter</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeSetFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Eav\Model\AttributeSetRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessorComposite</argument> + </arguments> + </type> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <arguments> + <argument name="customFilters" xsi:type="array"> + <item name="attribute_set_id" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeGroupAttributeSetIdFilter</item> + <item name="attribute_group_code" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeGroupCodeFilter</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupSortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> + <arguments> + <argument name="defaultOrders" xsi:type="array"> + <item name="sort_order" xsi:type="string">ASC</item> + </argument> + </arguments> + </virtualType> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <arguments> + <argument name="processors" xsi:type="array"> + <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupSortingProcessor</item> + <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Eav\Model\Attribute\GroupRepository"> + <arguments> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessorComposite</argument> + </arguments> + </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/Cms/Api/BlockRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Cms/Api/BlockRepositoryTest.php index 5dadcf92fee..dafb3746d8d 100644 --- a/dev/tests/api-functional/testsuite/Magento/Cms/Api/BlockRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Cms/Api/BlockRepositoryTest.php @@ -6,6 +6,10 @@ namespace Magento\Cms\Api; use Magento\Cms\Api\Data\BlockInterface; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -216,24 +220,45 @@ class BlockRepositoryTest extends WebapiAbstract { $cmsBlocks = $this->prepareCmsBlocks(); - $filterBuilder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class); - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */ + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ $searchCriteriaBuilder = Bootstrap::getObjectManager() - ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); - $filterIdentifier = $filterBuilder + ->create(SearchCriteriaBuilder::class); + + $filter1 = $filterBuilder ->setField(BlockInterface::IDENTIFIER) ->setValue($cmsBlocks['first']->getIdentifier()) ->create(); - $searchCriteriaBuilder->addFilters([$filterIdentifier]); - $filterTitle = $filterBuilder + $filter2 = $filterBuilder + ->setField(BlockInterface::IDENTIFIER) + ->setValue($cmsBlocks['third']->getIdentifier()) + ->create(); + $filter3 = $filterBuilder ->setField(BlockInterface::TITLE) ->setValue($cmsBlocks['second']->getTitle()) ->create(); - $filterStatus = $filterBuilder + $filter4 = $filterBuilder ->setField(BlockInterface::IS_ACTIVE) - ->setValue($cmsBlocks['first']->isActive()) + ->setValue(true) ->create(); - $searchCriteriaBuilder->addFilters([$filterTitle, $filterStatus]); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3, $filter4]); + + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(BlockInterface::IDENTIFIER) + ->setDirection(SortOrder::SORT_ASC) + ->create(); + + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(1); + $searchCriteriaBuilder->setCurrentPage(2); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -250,10 +275,11 @@ class BlockRepositoryTest extends WebapiAbstract ]; $searchResult = $this->_webApiCall($serviceInfo, $requestData); - $this->assertEquals(1, $searchResult['total_count']); + $this->assertEquals(2, $searchResult['total_count']); + $this->assertEquals(1, count($searchResult['items'])); $this->assertEquals( $searchResult['items'][0][BlockInterface::IDENTIFIER], - $cmsBlocks['first']->getIdentifier() + $cmsBlocks['third']->getIdentifier() ); } @@ -263,13 +289,19 @@ class BlockRepositoryTest extends WebapiAbstract private function prepareCmsBlocks() { $result = []; + $blocksData['first'][BlockInterface::TITLE] = 'Block title 1'; $blocksData['first'][BlockInterface::IDENTIFIER] = 'block-title-1' . uniqid(); $blocksData['first'][BlockInterface::IS_ACTIVE] = true; + $blocksData['second'][BlockInterface::TITLE] = 'Block title 2'; $blocksData['second'][BlockInterface::IDENTIFIER] = 'block-title-2' . uniqid(); $blocksData['second'][BlockInterface::IS_ACTIVE] = false; + $blocksData['third'][BlockInterface::TITLE] = 'Block title 3'; + $blocksData['third'][BlockInterface::IDENTIFIER] = 'block-title-3' . uniqid(); + $blocksData['third'][BlockInterface::IS_ACTIVE] = true; + foreach ($blocksData as $key => $blockData) { /** @var \Magento\Cms\Api\Data\BlockInterface $blockDataObject */ $blockDataObject = $this->blockFactory->create(); diff --git a/dev/tests/api-functional/testsuite/Magento/Cms/Api/PageRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Cms/Api/PageRepositoryTest.php index 26c7a907b50..98c1b91c265 100644 --- a/dev/tests/api-functional/testsuite/Magento/Cms/Api/PageRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Cms/Api/PageRepositoryTest.php @@ -6,6 +6,10 @@ namespace Magento\Cms\Api; use Magento\Cms\Api\Data\PageInterface; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; @@ -215,24 +219,47 @@ class PageRepositoryTest extends WebapiAbstract { $cmsPages = $this->prepareCmsPages(); - $filterBuilder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class); - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder */ + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ $searchCriteriaBuilder = Bootstrap::getObjectManager() - ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); - $filterIdentifier = $filterBuilder + ->create(SearchCriteriaBuilder::class); + + $filter1 = $filterBuilder ->setField(PageInterface::IDENTIFIER) ->setValue($cmsPages['first']->getIdentifier()) ->create(); - $searchCriteriaBuilder->addFilters([$filterIdentifier]); - $filterTitle = $filterBuilder + $filter2 = $filterBuilder + ->setField(PageInterface::IDENTIFIER) + ->setValue($cmsPages['third']->getIdentifier()) + ->create(); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + + $filter3 = $filterBuilder ->setField(PageInterface::TITLE) ->setValue($cmsPages['second']->getTitle()) ->create(); - $filterStatus = $filterBuilder + $filter4 = $filterBuilder ->setField(PageInterface::IS_ACTIVE) - ->setValue($cmsPages['first']->isActive()) + ->setValue(true) + ->create(); + + $searchCriteriaBuilder->addFilters([$filter3, $filter4]); + + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField(PageInterface::IDENTIFIER) + ->setDirection(SortOrder::SORT_ASC) ->create(); - $searchCriteriaBuilder->addFilters([$filterTitle, $filterStatus]); + + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(1); + $searchCriteriaBuilder->setCurrentPage(2); $searchData = $searchCriteriaBuilder->create()->__toArray(); $requestData = ['searchCriteria' => $searchData]; @@ -249,8 +276,12 @@ class PageRepositoryTest extends WebapiAbstract ]; $searchResult = $this->_webApiCall($serviceInfo, $requestData); - $this->assertEquals(1, $searchResult['total_count']); - $this->assertEquals($searchResult['items'][0][PageInterface::IDENTIFIER], $cmsPages['first']->getIdentifier()); + $this->assertEquals(2, $searchResult['total_count']); + $this->assertEquals(1, count($searchResult['items'])); + $this->assertEquals( + $searchResult['items'][0][PageInterface::IDENTIFIER], + $cmsPages['third']->getIdentifier() + ); } /** @@ -259,13 +290,19 @@ class PageRepositoryTest extends WebapiAbstract private function prepareCmsPages() { $result = []; + $pagesData['first'][PageInterface::TITLE] = 'Page title 1'; $pagesData['first'][PageInterface::IDENTIFIER] = 'page-title-1' . uniqid(); $pagesData['first'][PageInterface::IS_ACTIVE] = true; + $pagesData['second'][PageInterface::TITLE] = 'Page title 2'; $pagesData['second'][PageInterface::IDENTIFIER] = 'page-title-2' . uniqid(); $pagesData['second'][PageInterface::IS_ACTIVE] = false; + $pagesData['third'][PageInterface::TITLE] = 'Page title 3'; + $pagesData['third'][PageInterface::IDENTIFIER] = 'page-title-3' . uniqid(); + $pagesData['third'][PageInterface::IS_ACTIVE] = true; + foreach ($pagesData as $key => $pageData) { /** @var \Magento\Cms\Api\Data\PageInterface $pageDataObject */ $pageDataObject = $this->pageFactory->create(); diff --git a/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php index 4de337a1f57..69f3b0d5f81 100644 --- a/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php @@ -5,6 +5,11 @@ */ namespace Magento\Eav\Api; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; class AttributeSetRepositoryTest extends WebapiAbstract @@ -139,7 +144,7 @@ class AttributeSetRepositoryTest extends WebapiAbstract */ public function testDeleteByIdDefaultAttributeSet() { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var \Magento\Eav\Model\Config */ $eavConfig = $objectManager->create(\Magento\Eav\Model\Config::class); @@ -191,31 +196,54 @@ class AttributeSetRepositoryTest extends WebapiAbstract } /** - * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php + * @magentoApiDataFixture Magento/Eav/_files/attribute_set_for_search.php */ public function testGetList() { - $searchCriteria = [ - 'searchCriteria' => [ - 'filter_groups' => [ - [ - 'filters' => [ - [ - 'field' => 'entity_type_code', - 'value' => 'catalog_product', - 'condition_type' => 'eq', - ], - ], - ], - ], - 'current_page' => 1, - 'page_size' => 2, - ], - ]; + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager() + ->create(SearchCriteriaBuilder::class); + + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder + ->setField('entity_type_code') + ->setValue('catalog_product') + ->create(); + $filter2 = $filterBuilder + ->setField('sort_order') + ->setValue(200) + ->setConditionType('gteq') + ->create(); + $filter3 = $filterBuilder + ->setField('sort_order') + ->setValue(300) + ->setConditionType('lteq') + ->create(); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3]); + + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField('sort_order') + ->setDirection(SortOrder::SORT_ASC) + ->create(); + + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(1); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchData = $searchCriteriaBuilder->create()->__toArray(); + $requestData = ['searchCriteria' => $searchData]; $serviceInfo = [ 'rest' => [ - 'resourcePath' => '/V1/eav/attribute-sets/list' . '?' . http_build_query($searchCriteria), + 'resourcePath' => '/V1/eav/attribute-sets/list' . '?' . http_build_query($requestData), 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, ], 'soap' => [ @@ -225,18 +253,14 @@ class AttributeSetRepositoryTest extends WebapiAbstract ], ]; - $response = $this->_webApiCall($serviceInfo, $searchCriteria); - - $this->assertArrayHasKey('search_criteria', $response); - $this->assertArrayHasKey('total_count', $response); - $this->assertArrayHasKey('items', $response); - - $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']); - $this->assertTrue($response['total_count'] > 0); - $this->assertTrue(count($response['items']) > 0); + $searchResult = $this->_webApiCall($serviceInfo, $requestData); - $this->assertNotNull($response['items'][0]['attribute_set_id']); - $this->assertNotNull($response['items'][0]['attribute_set_name']); + $this->assertEquals(2, $searchResult['total_count']); + $this->assertEquals(1, count($searchResult['items'])); + $this->assertEquals( + $searchResult['items'][0]['attribute_set_name'], + 'attribute_set_3_for_search' + ); } /** @@ -248,7 +272,7 @@ class AttributeSetRepositoryTest extends WebapiAbstract */ protected function getAttributeSetByName($attributeSetName) { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */ $attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class) ->load($attributeSetName, 'attribute_set_name'); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php index 600db468d92..9e8a6a0bb9f 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php @@ -327,31 +327,23 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase } } - $searchResults = $this->repository->getList($searchBuilder->create()); + $searchBuilder->setPageSize(1); + $searchBuilder->setCurrentPage(2); + + $searchCriteria = $searchBuilder->create(); + $searchResults = $this->repository->getList($searchCriteria); + + $items = array_values($searchResults->getItems()); $this->assertEquals(count($expectedResult), $searchResults->getTotalCount()); + $this->assertEquals(1, count($items)); - $i = 0; - /** @var \Magento\Customer\Api\Data\AddressInterface $item*/ - foreach ($searchResults->getItems() as $item) { - $this->assertEquals( - $expectedResult[$i]['id'], - $item->getId() - ); - $this->assertEquals( - $expectedResult[$i]['city'], - $item->getCity() - ); - $this->assertEquals( - $expectedResult[$i]['postcode'], - $item->getPostcode() - ); - $this->assertEquals( - $expectedResult[$i]['firstname'], - $item->getFirstname() - ); - $i++; - } + $expectedResultIndex = count($expectedResult) - 1; + + $this->assertEquals($expectedResult[$expectedResultIndex]['id'], $items[0]->getId()); + $this->assertEquals($expectedResult[$expectedResultIndex]['city'], $items[0]->getCity()); + $this->assertEquals($expectedResult[$expectedResultIndex]['postcode'], $items[0]->getPostcode()); + $this->assertEquals($expectedResult[$expectedResultIndex]['firstname'], $items[0]->getFirstname()); } public function searchAddressDataProvider() @@ -371,13 +363,17 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase [$filterBuilder->setField('postcode')->setValue('75477')->create()], null, null, - [['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John']], + [ + ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], + ], ], 'Address with city CityM' => [ [$filterBuilder->setField('city')->setValue('CityM')->create()], null, null, - [['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John']], + [ + ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], + ], ], 'Addresses with firstname John sorted by firstname desc, city asc' => [ [$filterBuilder->setField('firstname')->setValue('John')->create()], diff --git a/dev/tests/integration/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php new file mode 100644 index 00000000000..8527628cb2a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php @@ -0,0 +1,85 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Attribute; + +use Magento\Eav\Api\AttributeGroupRepositoryInterface; +use Magento\Eav\Model\Entity\Attribute\Set; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\TestFramework\Helper\Bootstrap; + +class GroupRepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AttributeGroupRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(AttributeGroupRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Eav/_files/attribute_group_for_search.php + */ + public function testGetList() + { + /** @var Set $attributeSet */ + $attributeSet = Bootstrap::getObjectManager()->create(Set::class) + ->load('attribute_set_1_for_search', 'attribute_set_name'); + + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField('attribute_set_id') + ->setValue($attributeSet->getId()) + ->create(); + $filter2 = $filterBuilder->setField('default_id') + ->setValue(0) + ->setConditionType('eq') + ->create(); + $filter3 = $filterBuilder->setField('sort_order') + ->setValue(10) + ->setConditionType('gteq') + ->create(); + $filter4 = $filterBuilder->setField('sort_order') + ->setValue(30) + ->setConditionType('lteq') + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3, $filter4]); + + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField('attribute_group_code') + ->setDirection(SortOrder::SORT_ASC) + ->create(); + + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(1); + $searchCriteriaBuilder->setCurrentPage(1); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList($searchCriteria); + + $this->assertEquals(2, $searchResult->getTotalCount()); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('attribute_group_3_for_search', $items[0]['attribute_group_code']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeRepositoryTest.php new file mode 100644 index 00000000000..8c2052183cd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/Model/AttributeRepositoryTest.php @@ -0,0 +1,74 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model; + +use Magento\Eav\Api\AttributeRepositoryInterface; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\TestFramework\Helper\Bootstrap; + +class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var AttributeRepositoryInterface + */ + private $repository; + + protected function setUp() + { + $this->repository = Bootstrap::getObjectManager()->create(AttributeRepositoryInterface::class); + } + + /** + * @magentoDataFixture Magento/Eav/_files/attribute_for_search.php + */ + public function testGetList() + { + /** @var FilterBuilder $filterBuilder */ + $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class); + + $filter1 = $filterBuilder->setField('backend_type') + ->setValue('varchar') + ->create(); + $filter2 = $filterBuilder->setField('is_user_defined') + ->setValue(true) + ->create(); + $filter3 = $filterBuilder->setField('is_required') + ->setValue(true) + ->create(); + + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); + + $searchCriteriaBuilder->addFilters([$filter1, $filter2]); + $searchCriteriaBuilder->addFilters([$filter3]); + + /** @var SortOrderBuilder $sortOrderBuilder */ + $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class); + + /** @var SortOrder $sortOrder */ + $sortOrder = $sortOrderBuilder->setField('attribute_code') + ->setDirection(SortOrder::SORT_ASC) + ->create(); + + $searchCriteriaBuilder->setSortOrders([$sortOrder]); + + $searchCriteriaBuilder->setPageSize(2); + $searchCriteriaBuilder->setCurrentPage(2); + + $searchCriteria = $searchCriteriaBuilder->create(); + + $searchResult = $this->repository->getList('order', $searchCriteria); + + $this->assertEquals(3, $searchResult->getTotalCount()); + + $items = array_values($searchResult->getItems()); + $this->assertEquals(1, count($items)); + $this->assertEquals('attribute_for_search_3', $items[0]['attribute_code']); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_for_search.php b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_for_search.php new file mode 100644 index 00000000000..18ed2014719 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_for_search.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$entityTypeId = $objectManager->create(\Magento\Eav\Model\Entity\Type::class) + ->loadByCode('order') + ->getId(); + +$attributeData = [ + [ + 'attribute_code' => 'attribute_for_search_1', + 'entity_type_id' => $entityTypeId, + 'backend_type' => 'varchar', + 'is_required' => 1, + 'is_user_defined' => 1, + 'is_unique' => 0, + ], + [ + 'attribute_code' => 'attribute_for_search_2', + 'entity_type_id' => $entityTypeId, + 'backend_type' => 'varchar', + 'is_required' => 1, + 'is_user_defined' => 1, + 'is_unique' => 0, + ], + [ + 'attribute_code' => 'attribute_for_search_3', + 'entity_type_id' => $entityTypeId, + 'backend_type' => 'varchar', + 'is_required' => 1, + 'is_user_defined' => 1, + 'is_unique' => 0, + ], + [ + 'attribute_code' => 'attribute_for_search_4', + 'entity_type_id' => $entityTypeId, + 'backend_type' => 'int', + 'is_required' => 0, + 'is_user_defined' => 1, + 'is_unique' => 0, + ], + [ + 'attribute_code' => 'attribute_for_search_5', + 'entity_type_id' => $entityTypeId, + 'backend_type' => 'varchar', + 'is_required' => 0, + 'is_user_defined' => 1, + 'is_unique' => 0, + ], +]; + +foreach ($attributeData as $data) { + /** @var \Magento\Eav\Model\Entity\Attribute $attribute */ + $attribute = $objectManager->create(\Magento\Eav\Model\Entity\Attribute::class); + $attribute->setData($data); + $attribute->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_group_for_search.php b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_group_for_search.php new file mode 100644 index 00000000000..4400c7d90d1 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_group_for_search.php @@ -0,0 +1,55 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** + * Create attribute set + */ +$entityTypeId = $objectManager->create(\Magento\Eav\Model\Entity\Type::class) + ->loadByCode('catalog_product') + ->getId(); + +/** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */ +$attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class); +$attributeSet->setData([ + 'attribute_set_name' => 'attribute_set_1_for_search', + 'entity_type_id' => $entityTypeId, + 'sort_order' => 100, +]); +$attributeSet->validate(); +$attributeSet->save(); + +/** + * Create attribute groups + */ +$attributeGroupData = [ + [ + 'attribute_set_id' => $attributeSet->getAttributeSetId(), + 'sort_order' => 10, + 'attribute_group_code' => 'attribute_group_1_for_search', + 'default_id' => 1, + ], + [ + 'attribute_set_id' => $attributeSet->getAttributeSetId(), + 'sort_order' => 20, + 'attribute_group_code' => 'attribute_group_2_for_search', + 'default_id' => 0, + ], + [ + 'attribute_set_id' => $attributeSet->getAttributeSetId(), + 'sort_order' => 30, + 'attribute_group_code' => 'attribute_group_3_for_search', + 'default_id' => 0, + ], +]; + +foreach ($attributeGroupData as $data) { + /** @var \Magento\Eav\Model\Entity\Attribute\Group $attributeGroup */ + $attributeGroup = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Group::class); + $attributeGroup->setData($data); + $attributeGroup->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search.php b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search.php new file mode 100644 index 00000000000..c24dfcec7a6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$entityTypeId = $objectManager->create(\Magento\Eav\Model\Entity\Type::class) + ->loadByCode('catalog_product') + ->getId(); + +$attributeSetData = [ + [ + 'attribute_set_name' => 'attribute_set_1_for_search', + 'entity_type_id' => $entityTypeId, + 'sort_order' => 100, + ], + [ + 'attribute_set_name' => 'attribute_set_2_for_search', + 'entity_type_id' => $entityTypeId, + 'sort_order' => 200, + ], + [ + 'attribute_set_name' => 'attribute_set_3_for_search', + 'entity_type_id' => $entityTypeId, + 'sort_order' => 300, + ], + [ + 'attribute_set_name' => 'attribute_set_4_for_search', + 'entity_type_id' => $entityTypeId, + 'sort_order' => 400, + ], +]; + +foreach ($attributeSetData as $data) { + /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */ + $attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class); + $attributeSet->setData($data); + $attributeSet->validate(); + $attributeSet->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search_rollback.php b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search_rollback.php new file mode 100644 index 00000000000..e787e232631 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Eav/_files/attribute_set_for_search_rollback.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$attributeSetData = [ + 'attribute_set_1_for_search', + 'attribute_set_2_for_search', + 'attribute_set_3_for_search', + 'attribute_set_4_for_search', +]; + +foreach ($attributeSetData as $attributeSetName) { + /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */ + $attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class) + ->load($attributeSetName, 'attribute_set_name'); + if ($attributeSet->getId()) { + $attributeSet->delete(); + } +} -- GitLab From f885158e8b182767ce730a0b3e1699d0b01049ca Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Tue, 9 Aug 2016 16:28:46 -0500 Subject: [PATCH 228/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module - Fixed situation of escaping html content on frontend. --- .../view/frontend/templates/widget/static_block/default.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml b/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml index 4eb463ab3c3..bb7d392098b 100644 --- a/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml +++ b/app/code/Magento/Cms/view/frontend/templates/widget/static_block/default.phtml @@ -8,5 +8,5 @@ ?> <div class="widget block block-static-block"> - <?php echo $block->escapeHtml($block->getText()); ?> + <?php /* @noEscape */ echo $block->getText(); ?> </div> -- GitLab From 6dfb47142c1ca7e7ee04ae024d2fba7cdbbbe7e6 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 9 Aug 2016 17:39:21 -0500 Subject: [PATCH 229/838] MAGETWO-55927: Eliminate @escapeNotVerified in UrlRewrite Module --- .../Magento/UrlRewrite/Block/SelectorTest.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/UrlRewrite/Block/SelectorTest.php diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/SelectorTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/SelectorTest.php new file mode 100644 index 00000000000..15e949123a2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/SelectorTest.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\UrlRewrite\Block; + +/** + * Test for \Magento\UrlRewrite\Block\Selector + * @magentoAppArea adminhtml + */ +class SelectorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @magentoAppIsolation enabled + */ + public function testGetModeUrl() + { + /** @var $layout \Magento\Framework\View\LayoutInterface */ + $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\View\LayoutInterface::class + ); + + /** @var $block \Magento\UrlRewrite\Block\Selector */ + $block = $layout->createBlock(\Magento\UrlRewrite\Block\Selector::class); + + $modeUrl = $block->getModeUrl('mode'); + $this->assertEquals(1, preg_match('/admin\/index\/index\/key\/[0-9a-zA-Z]+\/mode/', $modeUrl)); + } +} -- GitLab From 09acdd13ca716e5ee09fd0fbdf1bdeda6a7005ac Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 9 Aug 2016 16:35:18 -0500 Subject: [PATCH 230/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../Catalog/Product/ConfigurationTest.php | 11 +- .../Customer/Wishlist/Item/OptionsTest.php | 143 ++++++++++++++++++ 2 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php diff --git a/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php b/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php index 2f560d5294c..d87b6b9a3c5 100644 --- a/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php @@ -164,6 +164,9 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase $this->assertEquals([], $this->helper->getBundleOptions($this->item)); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testGetOptions() { $optionIds = 'a:1:{i:0;i:1;}'; @@ -254,8 +257,12 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase $this->assertEquals( [ - 0 => ['label' => 'title', 'value' => [0 => '1 x name <span class="price">$15.00</span>']], - 1 => ['label' => 'title', 'value' => 'value'], + [ + 'label' => 'title', + 'value' => ['1 x name <span class="price">$15.00</span>'], + 'html_value' => true, + ], + ['label' => 'title', 'value' => 'value'], ], $this->helper->getOptions($this->item) ); diff --git a/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php b/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php new file mode 100644 index 00000000000..435448c92b8 --- /dev/null +++ b/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php @@ -0,0 +1,143 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Wishlist\Test\Unit\Block\Customer\Wishlist\Item; + +use Magento\Wishlist\Block\Customer\Wishlist\Item\Options; + +class OptionsTest extends \PHPUnit_Framework_TestCase +{ + const TEST_PRODUCT_TYPE = 'testProductType'; + const TEST_HELPER_CLASS_NAME = 'testHelperClass'; + + /** + * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject + */ + private $escaperMock; + + /** + * @var \Magento\Framework\App\Http\Context|\PHPUnit_Framework_MockObject_MockObject + */ + private $httpContextMock; + + /** + * @var Options + */ + private $block; + + /** + * @var \Magento\Catalog\Helper\Product\ConfigurationPool|\PHPUnit_Framework_MockObject_MockObject + */ + private $helperPoolMock; + + /** + * @var \Magento\Wishlist\Model\Item|\PHPUnit_Framework_MockObject_MockObject + */ + private $itemMock; + + protected function setUp() + { + $productContextMock = $this->getMockBuilder(\Magento\Catalog\Block\Product\Context::class) + ->disableOriginalConstructor() + ->getMock(); + $this->escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) + ->disableOriginalConstructor() + ->getMock(); + $eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $productContextMock->method('getEscaper') + ->willReturn($this->escaperMock); + $productContextMock->method('getEventManager') + ->willReturn($eventManagerMock); + + $this->httpContextMock = $this->getMockBuilder(\Magento\Framework\App\Http\Context::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->helperPoolMock = $this->getMockBuilder(\Magento\Catalog\Helper\Product\ConfigurationPool::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->itemMock = $this->getMockBuilder(\Magento\Wishlist\Model\Item::class) + ->disableOriginalConstructor() + ->getMock(); + + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->block = $objectManager->getObject( + Options::class, + [ + 'context' => $productContextMock, + 'httpContext' => $this->httpContextMock, + 'helperPool' => $this->helperPoolMock, + ] + ); + $this->block->setItem($this->itemMock); + $this->block->addOptionsRenderCfg(self::TEST_PRODUCT_TYPE, self::TEST_HELPER_CLASS_NAME); + } + + /** + * @param array $options + * @param int $callNum + * @param array $expected + * @dataProvider getConfiguredOptionsDataProvider + */ + public function testGetConfiguredOptions($options, $callNum, $expected) + { + $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->getMock(); + $productMock->expects($this->once()) + ->method('getTypeId') + ->willReturn(self::TEST_PRODUCT_TYPE); + $this->itemMock->expects($this->once()) + ->method('getProduct') + ->willReturn($productMock); + + $helperMock = $this->getMockBuilder(\Magento\Catalog\Helper\Product\Configuration\ConfigurationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $helperMock->expects($this->once()) + ->method('getOptions') + ->willReturn($options); + $this->helperPoolMock->expects($this->once()) + ->method('get') + ->with(self::TEST_HELPER_CLASS_NAME) + ->willReturn($helperMock); + + $this->escaperMock->expects($this->exactly($callNum)) + ->method('escapeHtml') + ->willReturnArgument(0); + + $this->assertEquals($expected, $this->block->getConfiguredOptions()); + } + + public function getConfiguredOptionsDataProvider() + { + return [ + [ + [ + [ + 'label' => 'title', + 'value' => ['1 x name <span class="price">$15.00</span>'], + 'html_value' => true, + ], + ['label' => 'title', 'value' => 'value'], + ['label' => 'title', 'value' => ['value']], + ], + 2, + [ + [ + 'label' => 'title', + 'value' => '1 x name <span class="price">$15.00</span>', + 'html_value' => true, + ], + ['label' => 'title', 'value' => 'value'], + ['label' => 'title', 'value' => 'value'], + ], + ] + ]; + } +} -- GitLab From 12afbc88ab69dccb903c8b7ef720450ba4c34724 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Mon, 25 Jul 2016 16:06:56 +0300 Subject: [PATCH 231/838] MAGETWO-56740: Implement Configurable Product wizard paging for mainline --- .../edit/attribute/steps/summary.phtml | 3 + .../web/js/variations/steps/summary.js | 71 ++++++++++++++----- .../variations/steps/summary-grid.html | 6 +- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml index 37bde42041b..2cc92451ffb 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/summary.phtml @@ -17,6 +17,7 @@ <!-- ko if: gridNew().length --> <!-- ko template: {name: getGridTemplate(), data: { grid: gridNew, + paging: pagingNew, id: getGridId(), title: $t('New Product Review'), note: $t('Here are the products you\'re about to create.') @@ -25,6 +26,7 @@ <!-- ko if: gridExisting().length --> <!-- ko template: {name: getGridTemplate(), data: { + paging: pagingExisting, grid: gridExisting, id: getGridId(), title: $t('Associated Products'), @@ -34,6 +36,7 @@ <!-- ko if: gridDeleted().length --> <!-- ko template: {name: getGridTemplate(), data: { + paging: pagingDeleted, grid: gridDeleted, id: getGridId(), title: $t('Disassociated Products'), diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js index de2c7aa1db5..f1c06b6d89b 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js @@ -8,8 +8,9 @@ define([ 'jquery', 'ko', 'underscore', + 'Magento_Ui/js/grid/paging/paging', 'mage/translate' -], function (Component, $, ko, _) { +], function (Component, $, ko, _, paging) { 'use strict'; return Component.extend({ @@ -25,22 +26,49 @@ define([ gridExisting: [], gridNew: [], gridDeleted: [], + variationsExisting: [], + variationsNew: [], + variationsDeleted: [], + pagingExisting: paging({ + name: 'configurableWizard.pagingExisting' + }), + pagingNew: paging({ + name: 'configurableWizard.pagingNew' + }), + pagingDeleted: paging({ + name: 'configurableWizard.pagingDeleted' + }), attributes: [], attributesName: [$.mage.__('Images'), $.mage.__('SKU'), $.mage.__('Quantity'), $.mage.__('Price')], sections: [], gridTemplate: 'Magento_ConfigurableProduct/variations/steps/summary-grid' }, initObservable: function () { + var pagingObservables = { + currentNew: ko.getObservable(this.pagingNew, 'current'), + currentExisting: ko.getObservable(this.pagingExisting, 'current'), + currentDeleted: ko.getObservable(this.pagingDeleted, 'current'), + pageSizeNew: ko.getObservable(this.pagingNew, 'pageSize'), + pageSizeExisting: ko.getObservable(this.pagingExisting, 'pageSize'), + pageSizeDeleted: ko.getObservable(this.pagingDeleted, 'pageSize') + }; + this._super().observe('gridExisting gridNew gridDeleted attributes sections'); this.gridExisting.columns = ko.observableArray(); this.gridNew.columns = ko.observableArray(); this.gridDeleted.columns = ko.observableArray(); + _.each(pagingObservables, function (observable) { + observable.subscribe(function () { + this.generateGrid(); + }, this); + }, this); + return this; }, nextLabelText: $.mage.__('Generate Products'), variations: [], - generateGrid: function (variations, getSectionValue) { + calculate: function (variations, getSectionValue) { var productSku = this.variationsComponent().getProductValue('sku'), productPrice = this.variationsComponent().getProductPrice(), productWeight = this.variationsComponent().getProductValue('weight'), @@ -48,8 +76,8 @@ define([ gridExisting = [], gridNew = [], gridDeleted = []; - this.variations = []; + this.variations = []; _.each(variations, function (options) { var product, images, sku, quantity, price, variation, productId = this.variationsComponent().getProductIdByOptions(options); @@ -101,14 +129,6 @@ define([ variationsKeys.push(this.variationsComponent().getVariationKey(options)); }, this); - this.gridExisting(gridExisting); - this.gridExisting.columns(this.getColumnsName(this.wizard.data.attributes)); - - if (gridNew.length > 0) { - this.gridNew(gridNew); - this.gridNew.columns(this.getColumnsName(this.wizard.data.attributes)); - } - _.each(_.omit(this.variationsComponent().productAttributesMap, variationsKeys), function (productId) { gridDeleted.push(this.prepareRowForGrid( _.findWhere(this.variationsComponent().variations, { @@ -117,13 +137,28 @@ define([ )); }.bind(this)); - if (gridDeleted.length > 0) { - this.gridDeleted(gridDeleted); - this.gridDeleted.columns(this.getColumnsName(this.variationsComponent().productAttributes)); - } + this.variationsExisting = gridExisting; + this.variationsNew = gridNew; + this.variationsDeleted = gridDeleted; + + }, + generateGrid: function () { + var pageExisting = this.pagingExisting.pageSize * this.pagingExisting.current, + pageNew = this.pagingNew.pageSize * this.pagingNew.current, + pageDeleted = this.pagingDeleted.pageSize * this.pagingDeleted.current; + + this.pagingExisting.totalRecords = this.variationsExisting.length; + this.gridExisting(this.variationsExisting.slice(pageExisting - this.pagingExisting.pageSize, pageExisting)); + + this.pagingNew.totalRecords = this.variationsNew.length; + this.gridNew(this.variationsNew.slice(pageNew - this.pagingNew.pageSize, pageNew)); + + this.pagingDeleted.totalRecords = this.variationsDeleted.length; + this.gridDeleted(this.variationsDeleted.slice(pageDeleted - this.pagingDeleted.pageSize, pageDeleted)); }, prepareRowForGrid: function (variation) { var row = []; + row.push(_.extend({ images: [] }, variation.images)); @@ -158,7 +193,11 @@ define([ this.gridNew([]); this.gridExisting([]); this.gridDeleted([]); - this.generateGrid(wizard.data.variations, wizard.data.sectionHelper); + this.gridExisting.columns(this.getColumnsName(this.wizard.data.attributes)); + this.gridNew.columns(this.getColumnsName(this.wizard.data.attributes)); + this.gridDeleted.columns(this.getColumnsName(this.variationsComponent().productAttributes)); + this.calculate(wizard.data.variations, wizard.data.sectionHelper); + this.generateGrid(); }, force: function () { this.variationsComponent().render(this.variations, this.attributes()); diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/template/variations/steps/summary-grid.html b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/template/variations/steps/summary-grid.html index 3c79b6555c6..ada2e2205e9 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/template/variations/steps/summary-grid.html +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/template/variations/steps/summary-grid.html @@ -13,6 +13,10 @@ </div> <div class="fieldset-wrapper-content in collapse" data-collapsed="true" data-bind="attr: {id: id}"> + <!-- ko template: { + name: "ui/grid/paging/paging", data: paging + } --> + <!-- /ko --> <div class="note" data-bind="text: note"></div> <table class="data-grid data-grid-configurable"> <thead> @@ -23,7 +27,7 @@ <tbody> <tr repeat="foreach: grid, item: '$product'"> - <!-- ko fastForEach: { data: $product(), as: 'property' } --> + <!-- ko foreach: { data: $product(), as: 'property' } --> <td if="property && property.preview" class="data-grid-thumbnail-cell"> <div class="images-uploaded"> <img data-bind="attr: {src: property.preview}"/> -- GitLab From 9deec042d4122546ceabfba229334befef9b5b38 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Tue, 9 Aug 2016 15:05:28 +0300 Subject: [PATCH 232/838] MAGETWO-56740: Implement Configurable Product wizard paging for mainline --- .../web/js/variations/paging/sizes.js | 29 +++++++++++++++++++ .../web/js/variations/steps/summary.js | 18 ++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/paging/sizes.js diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/paging/sizes.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/paging/sizes.js new file mode 100644 index 00000000000..92a83f1bbdd --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/paging/sizes.js @@ -0,0 +1,29 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'Magento_Ui/js/grid/paging/sizes' +], function (Sizes) { + 'use strict'; + + return Sizes.extend({ + defaults: { + excludedOptions: ['100', '200'] + }, + + /** + * @override + */ + initialize: function () { + this._super(); + + this.excludedOptions.forEach(function (excludedOption) { + delete this.options[excludedOption]; + }, this); + this.updateArray(); + + return this; + } + }); +}); diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js index f1c06b6d89b..c0d1dd642c8 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js @@ -30,13 +30,25 @@ define([ variationsNew: [], variationsDeleted: [], pagingExisting: paging({ - name: 'configurableWizard.pagingExisting' + name: 'configurableWizard.pagingExisting', + sizesConfig: { + component: 'Magento_ConfigurableProduct/js/variations/paging/sizes', + name: 'configurableWizard.pagingExisting_sizes' + } }), pagingNew: paging({ - name: 'configurableWizard.pagingNew' + name: 'configurableWizard.pagingNew', + sizesConfig: { + component: 'Magento_ConfigurableProduct/js/variations/paging/sizes', + name: 'configurableWizard.pagingNew_sizes' + } }), pagingDeleted: paging({ - name: 'configurableWizard.pagingDeleted' + name: 'configurableWizard.pagingDeleted', + sizesConfig: { + component: 'Magento_ConfigurableProduct/js/variations/paging/sizes', + name: 'configurableWizard.pagingDeleted_sizes' + } }), attributes: [], attributesName: [$.mage.__('Images'), $.mage.__('SKU'), $.mage.__('Quantity'), $.mage.__('Price')], -- GitLab From 6465a73e0550bede3182d3db3dec014e2bd42916 Mon Sep 17 00:00:00 2001 From: Rykh Oleksandr <orykh@magento.com> Date: Wed, 10 Aug 2016 10:49:18 +0300 Subject: [PATCH 233/838] MTA-3342: Add an ability to run specified variation from a test case - Updated validation --- .../testsuites/Magento/Mtf/TestSuite/InjectableTests.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php index 974e4ab89c2..507cf768acf 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests.php @@ -102,9 +102,9 @@ class InjectableTests extends \PHPUnit_Framework_TestSuite if (!isset($filter['filter'])) { $configData->setFileName($configFileName . '.xml')->load($configFilePath); } else { - preg_match('`variation::(.*?)$`', $filter['filter'], $variation); - if (isset($variation[1]) && !empty($variation[1])) { - $configData->setFileName('basic.xml')->load($configFilePath); + $isValid = preg_match('`variation::(.*?)$`', $filter['filter'], $variation); + if ($isValid === 1) { + $configData->setFileName($configFileName . '.xml')->load($configFilePath); $data['rule']['variation']['allow'][0]['name'][0]['value'] = $variation[1]; $configData->merge($data); } -- GitLab From b89bcb5bb0bd2f5b8fe6ed9d5f442b6f9eeafe15 Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Wed, 10 Aug 2016 11:38:22 +0300 Subject: [PATCH 234/838] MAGETWO-56573: Introduce and implement ShipmentItemCreationInterface --- .../Data/ShipmentItemCreationInterface.php | 35 ++++++++ .../Sales/Api/Data/ShipmentItemInterface.php | 33 +------ .../Model/Order/Shipment/ItemCreation.php | 86 +++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 1 + 4 files changed, 124 insertions(+), 31 deletions(-) create mode 100644 app/code/Magento/Sales/Api/Data/ShipmentItemCreationInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php diff --git a/app/code/Magento/Sales/Api/Data/ShipmentItemCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentItemCreationInterface.php new file mode 100644 index 00000000000..57c908fb88c --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/ShipmentItemCreationInterface.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Api\Data; + +/** + * Input argument for shipment item creation + * + * Interface ShipmentItemCreationInterface + * + * @api + */ +interface ShipmentItemCreationInterface extends LineItemInterface, +\Magento\Framework\Api\ExtensibleDataInterface +{ + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php index 03f8fba0b43..6d891371d04 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php @@ -12,7 +12,8 @@ namespace Magento\Sales\Api\Data; * document lists the products and their quantities in the delivery package. A product is an item in a shipment. * @api */ -interface ShipmentItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface +interface ShipmentItemInterface extends \Magento\Sales\Api\Data\LineItemInterface, +\Magento\Framework\Api\ExtensibleDataInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case @@ -102,13 +103,6 @@ interface ShipmentItemInterface extends \Magento\Framework\Api\ExtensibleDataInt */ public function getName(); - /** - * Gets the order item ID for the shipment item. - * - * @return int Order item ID. - */ - public function getOrderItemId(); - /** * Gets the parent ID for the shipment item. * @@ -130,13 +124,6 @@ interface ShipmentItemInterface extends \Magento\Framework\Api\ExtensibleDataInt */ public function getProductId(); - /** - * Gets the quantity for the shipment item. - * - * @return float Quantity. - */ - public function getQty(); - /** * Gets the row total for the shipment item. * @@ -190,14 +177,6 @@ interface ShipmentItemInterface extends \Magento\Framework\Api\ExtensibleDataInt */ public function setWeight($weight); - /** - * Sets the quantity for the shipment item. - * - * @param float $qty - * @return $this - */ - public function setQty($qty); - /** * Sets the product ID for the shipment item. * @@ -206,14 +185,6 @@ interface ShipmentItemInterface extends \Magento\Framework\Api\ExtensibleDataInt */ public function setProductId($id); - /** - * Sets the order item ID for the shipment item. - * - * @param int $id - * @return $this - */ - public function setOrderItemId($id); - /** * Sets the additional data for the shipment item. * diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php new file mode 100644 index 00000000000..ee0e2514535 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\ShipmentItemCreationInterface; + +/** + * Class ItemCreation + */ +class ItemCreation implements ShipmentItemCreationInterface +{ + /** + * @var int + */ + private $orderItemId; + + /** + * @var float + */ + private $qty; + + /** + * @var \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface + */ + private $extensionAttributes; + + //@codeCoverageIgnoreStart + /** + * {@inheritdoc} + */ + public function getOrderItemId() + { + return $this->orderItemId; + } + + /** + * {@inheritdoc} + */ + public function setOrderItemId($orderItemId) + { + $this->orderItemId = $orderItemId; + } + + /** + * {@inheritdoc} + */ + public function getQty() + { + return $this->qty; + } + + /** + * {@inheritdoc} + */ + public function setQty($qty) + { + $this->qty = $qty; + } + + /** + * {@inheritdoc} + * + * @return \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface|null + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * {@inheritdoc} + * + * @param \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentItemCreationExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + return $this; + } + //@codeCoverageIgnoreEnd +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 49fd2891fa9..a6c84816dd3 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -32,6 +32,7 @@ <preference for="Magento\Sales\Api\Data\ShipmentCommentSearchResultInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Comment\Collection"/> <preference for="Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface" type="Magento\Sales\Model\Order\Shipment\CreationArguments"/> <preference for="Magento\Sales\Api\Data\ShipmentInterface" type="Magento\Sales\Model\Order\Shipment"/> + <preference for="Magento\Sales\Api\Data\ShipmentItemCreationInterface" type="Magento\Sales\Model\Order\Shipment\ItemCreation"/> <preference for="Magento\Sales\Api\Data\ShipmentItemInterface" type="Magento\Sales\Model\Order\Shipment\Item"/> <preference for="Magento\Sales\Api\Data\ShipmentItemSearchResultInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Item\Collection"/> <preference for="Magento\Sales\Api\Data\ShipmentSearchResultInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Collection"/> -- GitLab From df93c112f2e4af28cc2a6f0c6ad1df106f21dc52 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 10 Aug 2016 11:42:26 +0300 Subject: [PATCH 235/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- .../Magento/Ui/Model/BookmarkManagement.php | 65 +++++++++---------- .../Unit/Model/BookmarkManagementTest.php | 8 +-- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/app/code/Magento/Ui/Model/BookmarkManagement.php b/app/code/Magento/Ui/Model/BookmarkManagement.php index bcfc137d930..83f1155d2cb 100644 --- a/app/code/Magento/Ui/Model/BookmarkManagement.php +++ b/app/code/Magento/Ui/Model/BookmarkManagement.php @@ -51,20 +51,19 @@ class BookmarkManagement implements \Magento\Ui\Api\BookmarkManagementInterface */ public function loadByNamespace($namespace) { - $this->searchCriteriaBuilder->addFilters( - [ - $this->filterBuilder - ->setField('user_id') - ->setConditionType('eq') - ->setValue($this->userContext->getUserId()) - ->create(), - $this->filterBuilder - ->setField('namespace') - ->setConditionType('eq') - ->setValue($namespace) - ->create(), - ] - ); + $userIdFilter = $this->filterBuilder + ->setField('user_id') + ->setConditionType('eq') + ->setValue($this->userContext->getUserId()) + ->create(); + $namespaceFilter = $this->filterBuilder + ->setField('namespace') + ->setConditionType('eq') + ->setValue($namespace) + ->create(); + + $this->searchCriteriaBuilder->addFilters([$userIdFilter]); + $this->searchCriteriaBuilder->addFilters([$namespaceFilter]); $searchCriteria = $this->searchCriteriaBuilder->create(); $searchResults = $this->bookmarkRepository->getList($searchCriteria); @@ -77,25 +76,25 @@ class BookmarkManagement implements \Magento\Ui\Api\BookmarkManagementInterface */ public function getByIdentifierNamespace($identifier, $namespace) { - $this->searchCriteriaBuilder->addFilters( - [ - $this->filterBuilder - ->setField('user_id') - ->setConditionType('eq') - ->setValue($this->userContext->getUserId()) - ->create(), - $this->filterBuilder - ->setField('identifier') - ->setConditionType('eq') - ->setValue($identifier) - ->create(), - $this->filterBuilder - ->setField('namespace') - ->setConditionType('eq') - ->setValue($namespace) - ->create(), - ] - ); + $userIdFilter = $this->filterBuilder + ->setField('user_id') + ->setConditionType('eq') + ->setValue($this->userContext->getUserId()) + ->create(); + $identifierFilter = $this->filterBuilder + ->setField('identifier') + ->setConditionType('eq') + ->setValue($identifier) + ->create(); + $namespaceFilter = $this->filterBuilder + ->setField('namespace') + ->setConditionType('eq') + ->setValue($namespace) + ->create(); + + $this->searchCriteriaBuilder->addFilters([$userIdFilter]); + $this->searchCriteriaBuilder->addFilters([$identifierFilter]); + $this->searchCriteriaBuilder->addFilters([$namespaceFilter]); $searchCriteria = $this->searchCriteriaBuilder->create(); $searchResults = $this->bookmarkRepository->getList($searchCriteria); diff --git a/app/code/Magento/Ui/Test/Unit/Model/BookmarkManagementTest.php b/app/code/Magento/Ui/Test/Unit/Model/BookmarkManagementTest.php index 4f2eb225ba0..10a665a0be3 100644 --- a/app/code/Magento/Ui/Test/Unit/Model/BookmarkManagementTest.php +++ b/app/code/Magento/Ui/Test/Unit/Model/BookmarkManagementTest.php @@ -89,9 +89,9 @@ class BookmarkManagementTest extends \PHPUnit_Framework_TestCase $this->filterBuilder->expects($this->at(1)) ->method('create') ->willReturn($fieldNamespace); - $this->searchCriteriaBuilder->expects($this->once()) + $this->searchCriteriaBuilder->expects($this->exactly(2)) ->method('addFilters') - ->with([$fieldUserId, $fieldNamespace]); + ->withConsecutive([[$fieldUserId]], [[$fieldNamespace]]); $this->searchCriteriaBuilder->expects($this->once()) ->method('create') ->willReturn($searchCriteria); @@ -147,9 +147,9 @@ class BookmarkManagementTest extends \PHPUnit_Framework_TestCase $this->filterBuilder->expects($this->at(2)) ->method('create') ->willReturn($fieldNamespace); - $this->searchCriteriaBuilder->expects($this->once()) + $this->searchCriteriaBuilder->expects($this->exactly(3)) ->method('addFilters') - ->with([$fieldUserId, $fieldIdentifier, $fieldNamespace]); + ->withConsecutive([[$fieldUserId]], [[$fieldIdentifier]], [[$fieldNamespace]]); $this->searchCriteriaBuilder->expects($this->once()) ->method('create') ->willReturn($searchCriteria); -- GitLab From 032908bcf6b52930fdc82f531fc825cec41b84a1 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Wed, 10 Aug 2016 11:49:14 +0300 Subject: [PATCH 236/838] MAGETWO-51575: Index action in CompleteBackup controller is not valid anymore --- setup/src/Magento/Setup/Controller/CompleteBackup.php | 4 ++-- .../Setup/Test/Unit/Controller/CompleteBackupTest.php | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/setup/src/Magento/Setup/Controller/CompleteBackup.php b/setup/src/Magento/Setup/Controller/CompleteBackup.php index d8996cca7fe..f194f02ed1f 100644 --- a/setup/src/Magento/Setup/Controller/CompleteBackup.php +++ b/setup/src/Magento/Setup/Controller/CompleteBackup.php @@ -18,8 +18,8 @@ class CompleteBackup extends AbstractActionController public function indexAction() { $view = new ViewModel; - $view->setTerminal(true); - $view->setTemplate('/magento/setup/complete-backup.phtml'); + $view->setTemplate('/error/404.phtml'); + $this->getResponse()->setStatusCode(\Zend\Http\Response::STATUS_CODE_404); return $view; } diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/CompleteBackupTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/CompleteBackupTest.php index 7101629502c..efe87a98889 100644 --- a/setup/src/Magento/Setup/Test/Unit/Controller/CompleteBackupTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Controller/CompleteBackupTest.php @@ -26,8 +26,11 @@ class CompleteBackupTest extends \PHPUnit_Framework_TestCase { $viewModel = $this->controller->indexAction(); $this->assertInstanceOf(\Zend\View\Model\ViewModel::class, $viewModel); - $this->assertTrue($viewModel->terminate()); - $this->assertSame('/magento/setup/complete-backup.phtml', $viewModel->getTemplate()); + $this->assertSame('/error/404.phtml', $viewModel->getTemplate()); + $this->assertSame( + \Zend\Http\Response::STATUS_CODE_404, + $this->controller->getResponse()->getStatusCode() + ); } public function testProgressAction() -- GitLab From 0a973e55ab479ff5b1945caa2247ecffe5a8e52f Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Wed, 10 Aug 2016 12:19:47 +0300 Subject: [PATCH 237/838] MAGETWO-56572: Introduce and implement ShipmentCommentCreationInterface --- .../Data/ShipmentCommentCreationInterface.php | 30 ++++++ .../Api/Data/ShipmentCommentInterface.php | 79 +-------------- .../Model/Order/Shipment/CommentCreation.php | 97 +++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 1 + 4 files changed, 130 insertions(+), 77 deletions(-) create mode 100644 app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php new file mode 100644 index 00000000000..62495a654ae --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Data; + +/** + * Interface ShipmentCommentCreationInterface + */ +interface ShipmentCommentCreationInterface extends \Magento\Framework\Api\ExtensibleDataInterface, + \Magento\Sales\Api\Data\CommentInterface +{ + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php index a67b0577a77..8c01cecd98d 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php @@ -12,15 +12,12 @@ namespace Magento\Sales\Api\Data; * document lists the products and their quantities in the delivery package. A shipment document can contain comments. * @api */ -interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleDataInterface +interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleDataInterface, + \Magento\Sales\Api\Data\CommentInterface, \Magento\Sales\Api\Data\EntityInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. */ - /* - * Entity ID. - */ - const ENTITY_ID = 'entity_id'; /* * Parent ID. */ @@ -29,55 +26,6 @@ interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleData * Is-customer-notified flag. */ const IS_CUSTOMER_NOTIFIED = 'is_customer_notified'; - /* - * Is-visible-on-storefront flag. - */ - const IS_VISIBLE_ON_FRONT = 'is_visible_on_front'; - /* - * Comment. - */ - const COMMENT = 'comment'; - /* - * Created-at timestamp. - */ - const CREATED_AT = 'created_at'; - - /** - * Gets the comment for the shipment. - * - * @return string Comment. - */ - public function getComment(); - - /** - * Gets the created-at timestamp for the shipment comment. - * - * @return string|null Created-at timestamp. - */ - public function getCreatedAt(); - - /** - * Sets the created-at timestamp for the shipment comment. - * - * @param string $createdAt timestamp - * @return $this - */ - public function setCreatedAt($createdAt); - - /** - * Gets the ID for the shipment comment. - * - * @return int|null Shipment comment ID. - */ - public function getEntityId(); - - /** - * Sets entity ID. - * - * @param int $entityId - * @return $this - */ - public function setEntityId($entityId); /** * Gets the is-customer-notified flag value for the shipment comment. @@ -86,13 +34,6 @@ interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleData */ public function getIsCustomerNotified(); - /** - * Gets the is-visible-on-storefront flag value for the shipment comment. - * - * @return int Is-visible-on-storefront flag value. - */ - public function getIsVisibleOnFront(); - /** * Gets the parent ID for the shipment comment. * @@ -116,22 +57,6 @@ interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleData */ public function setIsCustomerNotified($isCustomerNotified); - /** - * Sets the is-visible-on-storefront flag value for the shipment comment. - * - * @param int $isVisibleOnFront - * @return $this - */ - public function setIsVisibleOnFront($isVisibleOnFront); - - /** - * Sets the comment for the shipment. - * - * @param string $comment - * @return $this - */ - public function setComment($comment); - /** * Retrieve existing extension attributes object or create a new one. * diff --git a/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php new file mode 100644 index 00000000000..b32aa7bb297 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; + +/** + * Class CommentCreation + */ +class CommentCreation implements ShipmentCommentCreationInterface +{ + /** + * @var \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface + */ + private $extensionAttributes; + + /** + * @var string + */ + private $comment; + + /** + * @var int + */ + private $isVisibleOnFront; + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface|null + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface $extensionAttributes + ) + { + $this->extensionAttributes = $extensionAttributes; + return $this; + } + + /** + * Gets the comment for the invoice. + * + * @return string Comment. + */ + public function getComment() + { + return $this->comment; + } + + /** + * Sets the comment for the invoice. + * + * @param string $comment + * @return $this + */ + public function setComment($comment) + { + $this->comment = $comment; + return $this; + } + + /** + * Gets the is-visible-on-storefront flag value for the invoice. + * + * @return int Is-visible-on-storefront flag value. + */ + public function getIsVisibleOnFront() + { + return $this->isVisibleOnFront; + } + + /** + * Sets the is-visible-on-storefront flag value for the invoice. + * + * @param int $isVisibleOnFront + * @return $this + */ + public function setIsVisibleOnFront($isVisibleOnFront) + { + $this->isVisibleOnFront = $isVisibleOnFront; + return $isVisibleOnFront; + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index d16fdc11c29..cc10bb9a917 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -52,6 +52,7 @@ <preference for="Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface" type="Magento\Sales\Model\Order\Invoice\CreationArguments"/> <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> <preference for="Magento\Sales\Api\Data\InvoiceCommentCreationInterface" type="Magento\Sales\Model\Order\Invoice\CommentCreation"/> + <preference for="Magento\Sales\Api\Data\ShipmentCommentCreationInterface" type="Magento\Sales\Model\Order\Shipment\CommentCreation"/> <preference for="Magento\Sales\Api\OrderAddressRepositoryInterface" type="Magento\Sales\Model\Order\AddressRepository"/> <preference for="Magento\Sales\Api\OrderCustomerManagementInterface" type="Magento\Sales\Model\Order\CustomerManagement"/> <preference for="Magento\Sales\Api\OrderItemRepositoryInterface" type="Magento\Sales\Model\Order\ItemRepository"/> -- GitLab From e4c209a6bca44c0b17f36fa3024d8aa857f73fe2 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 10 Aug 2016 12:27:43 +0300 Subject: [PATCH 238/838] MAGETWO-56743: Unable to upgrade with split databases --- app/code/Magento/Quote/Setup/QuoteSetup.php | 20 +++-- app/code/Magento/Quote/Setup/Recurring.php | 73 ------------------- .../Magento/Quote/Setup/UpgradeSchema.php | 15 ++-- app/code/Magento/Sales/Setup/SalesSetup.php | 24 ++++-- .../Magento/Sales/Setup/UpgradeSchema.php | 33 +++++---- .../Magento/Framework/Module/Setup.php | 30 ++++++-- setup/src/Magento/Setup/Module/Setup.php | 29 ++++++-- 7 files changed, 109 insertions(+), 115 deletions(-) delete mode 100644 app/code/Magento/Quote/Setup/Recurring.php diff --git a/app/code/Magento/Quote/Setup/QuoteSetup.php b/app/code/Magento/Quote/Setup/QuoteSetup.php index 2608580cf8f..1ef5f4b0dae 100644 --- a/app/code/Magento/Quote/Setup/QuoteSetup.php +++ b/app/code/Magento/Quote/Setup/QuoteSetup.php @@ -29,6 +29,11 @@ class QuoteSetup extends EavSetup */ protected $_encryptor; + /** + * @var string + */ + private static $connectionName = 'checkout'; + /** * @param ModuleDataSetupInterface $setup * @param Context $context @@ -70,8 +75,11 @@ class QuoteSetup extends EavSetup */ protected function _flatTableExist($table) { - $tablesList = $this->getSetup()->getConnection()->listTables(); - return in_array(strtoupper($this->getSetup()->getTable($table)), array_map('strtoupper', $tablesList)); + $tablesList = $this->getSetup()->getConnection(self::$connectionName)->listTables(); + return in_array( + strtoupper($this->getSetup()->getTable($table, self::$connectionName)), + array_map('strtoupper', $tablesList) + ); } /** @@ -107,13 +115,15 @@ class QuoteSetup extends EavSetup */ protected function _addFlatAttribute($table, $attribute, $attr) { - $tableInfo = $this->getSetup()->getConnection()->describeTable($this->getSetup()->getTable($table)); + $tableInfo = $this->getSetup() + ->getConnection(self::$connectionName) + ->describeTable($this->getSetup()->getTable($table, self::$connectionName)); if (isset($tableInfo[$attribute])) { return $this; } $columnDefinition = $this->_getAttributeColumnDefinition($attribute, $attr); - $this->getSetup()->getConnection()->addColumn( - $this->getSetup()->getTable($table), + $this->getSetup()->getConnection(self::$connectionName)->addColumn( + $this->getSetup()->getTable($table, self::$connectionName), $attribute, $columnDefinition ); diff --git a/app/code/Magento/Quote/Setup/Recurring.php b/app/code/Magento/Quote/Setup/Recurring.php deleted file mode 100644 index 03fe30bf802..00000000000 --- a/app/code/Magento/Quote/Setup/Recurring.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Quote\Setup; - -use Magento\Framework\Setup\ExternalFKSetup; -use Magento\Framework\Setup\InstallSchemaInterface; -use Magento\Framework\Setup\ModuleContextInterface; -use Magento\Framework\Setup\SchemaSetupInterface; -use Magento\Framework\EntityManager\MetadataPool; -use Magento\Catalog\Api\Data\ProductInterface; - -/** - * @codeCoverageIgnore - */ -class Recurring implements InstallSchemaInterface -{ - /** - * @var MetadataPool - */ - protected $metadataPool; - - /** - * @var ExternalFKSetup - */ - protected $externalFKSetup; - - /** - * @param MetadataPool $metadataPool - * @param ExternalFKSetup $externalFKSetup - */ - public function __construct( - MetadataPool $metadataPool, - ExternalFKSetup $externalFKSetup - ) { - $this->metadataPool = $metadataPool; - $this->externalFKSetup = $externalFKSetup; - } - - /** - * {@inheritdoc} - */ - public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) - { - $installer = $setup; - $installer->startSetup(); - - $this->addExternalForeignKeys($installer); - - $installer->endSetup(); - } - - /** - * Add external foreign keys - * - * @param SchemaSetupInterface $installer - * @return void - * @throws \Exception - */ - protected function addExternalForeignKeys(SchemaSetupInterface $installer) - { - $metadata = $this->metadataPool->getMetadata(ProductInterface::class); - $this->externalFKSetup->install( - $installer, - $metadata->getEntityTable(), - $metadata->getIdentifierField(), - 'quote_item', - 'product_id' - ); - } -} diff --git a/app/code/Magento/Quote/Setup/UpgradeSchema.php b/app/code/Magento/Quote/Setup/UpgradeSchema.php index 602f93e0445..fd9eec1e9e6 100644 --- a/app/code/Magento/Quote/Setup/UpgradeSchema.php +++ b/app/code/Magento/Quote/Setup/UpgradeSchema.php @@ -14,6 +14,11 @@ use Magento\Framework\Setup\SchemaSetupInterface; */ class UpgradeSchema implements UpgradeSchemaInterface { + /** + * @var string + */ + private static $connectionName = 'checkout'; + /** * {@inheritdoc} */ @@ -22,16 +27,16 @@ class UpgradeSchema implements UpgradeSchemaInterface $setup->startSetup(); if (version_compare($context->getVersion(), '2.0.1', '<')) { - $setup->getConnection()->addIndex( - $setup->getTable('quote_id_mask'), - $setup->getIdxName('quote_id_mask', ['masked_id']), + $setup->getConnection(self::$connectionName)->addIndex( + $setup->getTable('quote_id_mask', self::$connectionName), + $setup->getIdxName('quote_id_mask', ['masked_id'], '', self::$connectionName), ['masked_id'] ); } if (version_compare($context->getVersion(), '2.0.2', '<')) { - $setup->getConnection()->changeColumn( - $setup->getTable('quote_address'), + $setup->getConnection(self::$connectionName)->changeColumn( + $setup->getTable('quote_address', self::$connectionName), 'street', 'street', [ diff --git a/app/code/Magento/Sales/Setup/SalesSetup.php b/app/code/Magento/Sales/Setup/SalesSetup.php index 7a349bac35c..470abce8bf8 100644 --- a/app/code/Magento/Sales/Setup/SalesSetup.php +++ b/app/code/Magento/Sales/Setup/SalesSetup.php @@ -48,6 +48,11 @@ class SalesSetup extends \Magento\Eav\Setup\EavSetup */ protected $encryptor; + /** + * @var string + */ + private static $connectionName = 'sales'; + /** * @param ModuleDataSetupInterface $setup * @param Context $context @@ -105,8 +110,11 @@ class SalesSetup extends \Magento\Eav\Setup\EavSetup */ protected function _flatTableExist($table) { - $tablesList = $this->getSetup()->getConnection()->listTables(); - return in_array(strtoupper($this->getSetup()->getTable($table)), array_map('strtoupper', $tablesList)); + $tablesList = $this->getSetup()->getConnection(self::$connectionName)->listTables(); + return in_array( + strtoupper($this->getSetup()->getTable($table, self::$connectionName)), + array_map('strtoupper', $tablesList) + ); } /** @@ -143,13 +151,15 @@ class SalesSetup extends \Magento\Eav\Setup\EavSetup */ protected function _addFlatAttribute($table, $attribute, $attr) { - $tableInfo = $this->getSetup()->getConnection()->describeTable($this->getSetup()->getTable($table)); + $tableInfo = $this->getSetup() + ->getConnection(self::$connectionName) + ->describeTable($this->getSetup()->getTable($table, self::$connectionName)); if (isset($tableInfo[$attribute])) { return $this; } $columnDefinition = $this->_getAttributeColumnDefinition($attribute, $attr); - $this->getSetup()->getConnection()->addColumn( - $this->getSetup()->getTable($table), + $this->getSetup()->getConnection(self::$connectionName)->addColumn( + $this->getSetup()->getTable($table, self::$connectionName), $attribute, $columnDefinition ); @@ -169,8 +179,8 @@ class SalesSetup extends \Magento\Eav\Setup\EavSetup { if (in_array($entityTypeId, $this->_flatEntitiesGrid) && !empty($attr['grid'])) { $columnDefinition = $this->_getAttributeColumnDefinition($attribute, $attr); - $this->getSetup()->getConnection()->addColumn( - $this->getSetup()->getTable($table . '_grid'), + $this->getSetup()->getConnection(self::$connectionName)->addColumn( + $this->getSetup()->getTable($table . '_grid', self::$connectionName), $attribute, $columnDefinition ); diff --git a/app/code/Magento/Sales/Setup/UpgradeSchema.php b/app/code/Magento/Sales/Setup/UpgradeSchema.php index 907d782e8de..502e2e99e29 100644 --- a/app/code/Magento/Sales/Setup/UpgradeSchema.php +++ b/app/code/Magento/Sales/Setup/UpgradeSchema.php @@ -7,13 +7,17 @@ namespace Magento\Sales\Setup; use Magento\Framework\Setup\UpgradeSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; -use Magento\Framework\DB\Adapter\AdapterInterface; /** * @codeCoverageIgnore */ class UpgradeSchema implements UpgradeSchemaInterface { + /** + * @var string + */ + private static $connectionName = 'sales'; + /** * {@inheritdoc} */ @@ -22,34 +26,37 @@ class UpgradeSchema implements UpgradeSchemaInterface $installer = $setup; $installer->startSetup(); if (version_compare($context->getVersion(), '2.0.2', '<')) { - $connection = $installer->getConnection(); + $connection = $installer->getConnection(self::$connectionName); //sales_bestsellers_aggregated_daily $connection->dropForeignKey( - $installer->getTable('sales_bestsellers_aggregated_daily'), + $installer->getTable('sales_bestsellers_aggregated_daily', self::$connectionName), $installer->getFkName( 'sales_bestsellers_aggregated_daily', 'product_id', 'catalog_product_entity', - 'entity_id') + 'entity_id', + self::$connectionName) ); //sales_bestsellers_aggregated_monthly $connection->dropForeignKey( - $installer->getTable('sales_bestsellers_aggregated_monthly'), + $installer->getTable('sales_bestsellers_aggregated_monthly', self::$connectionName), $installer->getFkName( 'sales_bestsellers_aggregated_monthly', 'product_id', 'catalog_product_entity', - 'entity_id') + 'entity_id', + self::$connectionName) ); //sales_bestsellers_aggregated_yearly $connection->dropForeignKey( - $installer->getTable('sales_bestsellers_aggregated_yearly'), + $installer->getTable('sales_bestsellers_aggregated_yearly', self::$connectionName), $installer->getFkName( 'sales_bestsellers_aggregated_yearly', 'product_id', 'catalog_product_entity', - 'entity_id') + 'entity_id', + self::$connectionName) ); $installer->endSetup(); @@ -66,9 +73,9 @@ class UpgradeSchema implements UpgradeSchemaInterface */ private function addColumnBaseGrandTotal(SchemaSetupInterface $installer) { - $connection = $installer->getConnection(); + $connection = $installer->getConnection(self::$connectionName); $connection->addColumn( - $installer->getTable('sales_invoice_grid'), + $installer->getTable('sales_invoice_grid', self::$connectionName), 'base_grand_total', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, @@ -86,10 +93,10 @@ class UpgradeSchema implements UpgradeSchemaInterface */ private function addIndexBaseGrandTotal(SchemaSetupInterface $installer) { - $connection = $installer->getConnection(); + $connection = $installer->getConnection(self::$connectionName); $connection->addIndex( - $installer->getTable('sales_invoice_grid'), - $installer->getIdxName('sales_invoice_grid', ['base_grand_total']), + $installer->getTable('sales_invoice_grid', self::$connectionName), + $installer->getIdxName('sales_invoice_grid', ['base_grand_total'], '', self::$connectionName), ['base_grand_total'] ); } diff --git a/lib/internal/Magento/Framework/Module/Setup.php b/lib/internal/Magento/Framework/Module/Setup.php index 0b0bbb20a33..e590e09320e 100644 --- a/lib/internal/Magento/Framework/Module/Setup.php +++ b/lib/internal/Magento/Framework/Module/Setup.php @@ -9,6 +9,7 @@ namespace Magento\Framework\Module; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\SetupInterface; +use Magento\Framework\App\ResourceConnection; class Setup implements SetupInterface { @@ -57,9 +58,25 @@ class Setup implements SetupInterface /** * Get connection object * + * @param string|null $connectionName * @return \Magento\Framework\DB\Adapter\AdapterInterface */ - public function getConnection() + public function getConnection($connectionName = null) + { + if ($connectionName !== null) { + try { + return $this->resourceModel->getConnectionByName($connectionName); + } catch (\DomainException $exception) { + //Fallback to default connection + } + } + return $this->getDefaultConnection(); + } + + /** + * @return \Magento\Framework\DB\Adapter\AdapterInterface + */ + private function getDefaultConnection() { if (null === $this->connection) { $this->connection = $this->resourceModel->getConnection($this->connectionName); @@ -95,13 +112,14 @@ class Setup implements SetupInterface * Get table name (validated by db adapter) by table placeholder * * @param string|array $tableName + * @param string $connectionName * @return string */ - public function getTable($tableName) + public function getTable($tableName, $connectionName = ResourceConnection::DEFAULT_CONNECTION) { $cacheKey = $this->_getTableCacheName($tableName); if (!isset($this->tables[$cacheKey])) { - $this->tables[$cacheKey] = $this->resourceModel->getTableName($tableName); + $this->tables[$cacheKey] = $this->resourceModel->getTableName($tableName, $connectionName); } return $this->tables[$cacheKey]; } @@ -126,10 +144,10 @@ class Setup implements SetupInterface * @param string $table * @return bool */ - public function tableExists($table) + public function tableExists($table, $connectionName = ResourceConnection::DEFAULT_CONNECTION) { - $table = $this->getTable($table); - return $this->getConnection()->isTableExists($table); + $table = $this->getTable($table, $connectionName); + return $this->getConnection($connectionName)->isTableExists($table); } /** diff --git a/setup/src/Magento/Setup/Module/Setup.php b/setup/src/Magento/Setup/Module/Setup.php index 4451267a0e9..39fa5cbda13 100644 --- a/setup/src/Magento/Setup/Module/Setup.php +++ b/setup/src/Magento/Setup/Module/Setup.php @@ -6,6 +6,7 @@ namespace Magento\Setup\Module; use Magento\Framework\Setup\SchemaSetupInterface; +use Magento\Framework\App\ResourceConnection; class Setup extends \Magento\Framework\Module\Setup implements SchemaSetupInterface { @@ -15,11 +16,16 @@ class Setup extends \Magento\Framework\Module\Setup implements SchemaSetupInterf * @param string $tableName * @param array|string $fields * @param string $indexType + * @param string $connectionName * @return string */ - public function getIdxName($tableName, $fields, $indexType = '') - { - return $this->getConnection()->getIndexName($tableName, $fields, $indexType); + public function getIdxName( + $tableName, + $fields, + $indexType = '', + $connectionName = ResourceConnection::DEFAULT_CONNECTION + ) { + return $this->getConnection($connectionName)->getIndexName($tableName, $fields, $indexType); } /** @@ -29,10 +35,21 @@ class Setup extends \Magento\Framework\Module\Setup implements SchemaSetupInterf * @param string $priColumnName the target table column name * @param string $refTableName the reference table name * @param string $refColumnName the reference table column name + * @param string $connectionName * @return string */ - public function getFkName($priTableName, $priColumnName, $refTableName, $refColumnName) - { - return $this->getConnection()->getForeignKeyName($priTableName, $priColumnName, $refTableName, $refColumnName); + public function getFkName( + $priTableName, + $priColumnName, + $refTableName, + $refColumnName, + $connectionName = ResourceConnection::DEFAULT_CONNECTION + ) { + return $this->getConnection($connectionName)->getForeignKeyName( + $priTableName, + $priColumnName, + $refTableName, + $refColumnName + ); } } -- GitLab From f44981e5cfc64f9b9abd2dc84f60b435767e7cbd Mon Sep 17 00:00:00 2001 From: Michail Slabko <mslabko@magento.com> Date: Wed, 10 Aug 2016 12:26:18 +0300 Subject: [PATCH 239/838] MAGETWO-56591: Configurable product doesn't visible in category on frontend after creation --- .../Indexer/LinkedProductSelectBuilderByIndexPrice.php | 5 +++-- .../Product/LinkedProductSelectBuilderByBasePrice.php | 6 ++++-- .../Product/LinkedProductSelectBuilderBySpecialPrice.php | 5 +++-- .../Product/LinkedProductSelectBuilderByTierPrice.php | 6 ++++-- .../LinkedProductSelectBuilderByCatalogRulePrice.php | 5 +++-- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php index a5fd809e5cc..ea72691ea00 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/LinkedProductSelectBuilderByIndexPrice.php @@ -56,15 +56,16 @@ class LinkedProductSelectBuilderByIndexPrice implements LinkedProductSelectBuild public function build($productId) { $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $productTable = $this->resource->getTableName('catalog_product_entity'); return [$this->resource->getConnection()->select() - ->from(['parent' => 'catalog_product_entity'], '') + ->from(['parent' => $productTable], '') ->joinInner( ['link' => $this->resource->getTableName('catalog_product_relation')], "link.parent_id = parent.$linkField", [] )->joinInner( - ['child' => 'catalog_product_entity'], + ['child' => $productTable], "child.entity_id = link.child_id", ['entity_id'] )->joinInner( diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php index 934c094fecb..d325ab1a9a0 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByBasePrice.php @@ -65,14 +65,16 @@ class LinkedProductSelectBuilderByBasePrice implements LinkedProductSelectBuilde { $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $priceAttribute = $this->eavConfig->getAttribute(Product::ENTITY, 'price'); + $productTable = $this->resource->getTableName('catalog_product_entity'); + $priceSelect = $this->resource->getConnection()->select() - ->from(['parent' => 'catalog_product_entity'], '') + ->from(['parent' => $productTable], '') ->joinInner( ['link' => $this->resource->getTableName('catalog_product_relation')], "link.parent_id = parent.$linkField", [] )->joinInner( - ['child' => 'catalog_product_entity'], + ['child' => $productTable], "child.entity_id = link.child_id", ['entity_id'] )->joinInner( diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php index 77c786ed185..792a8f5b86d 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderBySpecialPrice.php @@ -86,15 +86,16 @@ class LinkedProductSelectBuilderBySpecialPrice implements LinkedProductSelectBui $specialPriceToDate = $this->eavConfig->getAttribute(Product::ENTITY, 'special_to_date'); $timestamp = $this->localeDate->scopeTimeStamp($this->storeManager->getStore()); $currentDate = $this->dateTime->formatDate($timestamp, false); + $productTable = $this->resource->getTableName('catalog_product_entity'); $specialPrice = $this->resource->getConnection()->select() - ->from(['parent' => 'catalog_product_entity'], '') + ->from(['parent' => $productTable], '') ->joinInner( ['link' => $this->resource->getTableName('catalog_product_relation')], "link.parent_id = parent.$linkField", [] )->joinInner( - ['child' => 'catalog_product_entity'], + ['child' => $productTable], "child.entity_id = link.child_id", ['entity_id'] )->joinInner( diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php index 399dffe14c9..d2d6d89c0a2 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/LinkedProductSelectBuilderByTierPrice.php @@ -68,14 +68,16 @@ class LinkedProductSelectBuilderByTierPrice implements LinkedProductSelectBuilde public function build($productId) { $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $productTable = $this->resource->getTableName('catalog_product_entity'); + $priceSelect = $this->resource->getConnection()->select() - ->from(['parent' => 'catalog_product_entity'], '') + ->from(['parent' => $productTable], '') ->joinInner( ['link' => $this->resource->getTableName('catalog_product_relation')], "link.parent_id = parent.$linkField", [] )->joinInner( - ['child' => 'catalog_product_entity'], + ['child' => $productTable], "child.entity_id = link.child_id", ['entity_id'] )->joinInner( diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php index 737c15115c1..7d8d44dcbb6 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php @@ -74,15 +74,16 @@ class LinkedProductSelectBuilderByCatalogRulePrice implements LinkedProductSelec $timestamp = $this->localeDate->scopeTimeStamp($this->storeManager->getStore()); $currentDate = $this->dateTime->formatDate($timestamp, false); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); + $productTable = $this->resource->getTableName('catalog_product_entity'); return [$this->resource->getConnection()->select() - ->from(['parent' => 'catalog_product_entity'], '') + ->from(['parent' => $productTable], '') ->joinInner( ['link' => $this->resource->getTableName('catalog_product_relation')], "link.parent_id = parent.$linkField", [] )->joinInner( - ['child' => 'catalog_product_entity'], + ['child' => $productTable], "child.entity_id = link.child_id", ['entity_id'] )->joinInner( -- GitLab From e8fddbe2f4e5ed5500a5c119eb9415347332442f Mon Sep 17 00:00:00 2001 From: Sergey Semenov <ssemenov@magento.com> Date: Wed, 10 Aug 2016 12:42:26 +0300 Subject: [PATCH 240/838] MAGETWO-56079: SearchCriteria Unified Processing for Cms, Customer and Eav modules --- .../AttributeGroupAttributeSetIdFilter.php | 10 ++- .../AttributeGroupCodeFilter.php | 8 +-- .../FilterProcessor/AttributeIdFilter.php | 36 ---------- .../AttributeSetEntityTypeCodeFilter.php | 14 ++-- .../Magento/Eav/Model/AttributeRepository.php | 2 +- .../AttributeGroupCodeFilterTest.php | 19 ----- .../FilterProcessor/AttributeIdFilterTest.php | 69 ------------------- .../AttributeSetEntityTypeCodeFilterTest.php | 19 ----- .../AttributeSetIdFilterTest.php | 19 ----- app/code/Magento/Eav/etc/di.xml | 24 ++----- 10 files changed, 21 insertions(+), 199 deletions(-) delete mode 100644 app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php delete mode 100644 app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php index a5de394668b..f9e2e154ca5 100644 --- a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilter.php @@ -20,11 +20,9 @@ class AttributeGroupAttributeSetIdFilter implements CustomFilterInterface */ public function apply(Filter $filter, AbstractDb $collection) { - if ($filter->getField() == 'attribute_set_id') { - /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\Collection $collection */ - $collection->setAttributeSetFilter($filter->getValue()); - return true; - } - return false; + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\Collection $collection */ + $collection->setAttributeSetFilter($filter->getValue()); + + return true; } } diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php index 68e07c61809..b7972fc88f9 100644 --- a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilter.php @@ -20,10 +20,8 @@ class AttributeGroupCodeFilter implements CustomFilterInterface */ public function apply(Filter $filter, AbstractDb $collection) { - if ($filter->getField() == 'attribute_group_code') { - $collection->addFilter('attribute_group_code', $filter->getValue()); - return true; - } - return false; + $collection->addFilter('attribute_group_code', $filter->getValue()); + + return true; } } diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php deleted file mode 100644 index 72c2f8f08c2..00000000000 --- a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilter.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; - -use Magento\Eav\Api\Data\AttributeInterface; -use Magento\Framework\Api\Filter; -use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; -use Magento\Framework\Data\Collection\AbstractDb; - -class AttributeIdFilter implements CustomFilterInterface -{ - /** - * Apply attribute ID filter to collection - * - * Prevent ambiguity during filtration - * - * @param Filter $filter - * @param AbstractDb $collection - * @return bool - */ - public function apply(Filter $filter, AbstractDb $collection) - { - if ($filter->getField() == AttributeInterface::ATTRIBUTE_ID) { - $conditionType = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $collection->addFieldToFilter( - 'main_table.' . $filter->getField(), - [$conditionType => $filter->getValue()] - ); - return true; - } - return false; - } -} diff --git a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php index 7c0cb795746..ac5a267ef31 100644 --- a/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php +++ b/app/code/Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilter.php @@ -35,13 +35,11 @@ class AttributeSetEntityTypeCodeFilter implements CustomFilterInterface */ public function apply(Filter $filter, AbstractDb $collection) { - if ($filter->getField() == 'entity_type_code') { - $entityTypeCode = $filter->getValue(); - $entityType = $this->eavConfig->getEntityType($entityTypeCode); - /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $collection */ - $collection->setEntityTypeFilter($entityType->getId()); - return true; - } - return false; + $entityType = $this->eavConfig->getEntityType($filter->getValue()); + + /** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $collection */ + $collection->setEntityTypeFilter($entityType->getId()); + + return true; } } diff --git a/app/code/Magento/Eav/Model/AttributeRepository.php b/app/code/Magento/Eav/Model/AttributeRepository.php index b108c20e64b..29b3ca10e70 100644 --- a/app/code/Magento/Eav/Model/AttributeRepository.php +++ b/app/code/Magento/Eav/Model/AttributeRepository.php @@ -228,7 +228,7 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Eav\Model\Api\SearchCriteria\AttributeCollectionProcessorComposite' + 'Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php index fdef7b46a0c..00937023c34 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupCodeFilterTest.php @@ -28,9 +28,6 @@ class AttributeGroupCodeFilterTest extends \PHPUnit_Framework_TestCase $filterMock = $this->getMockBuilder(Filter::class) ->disableOriginalConstructor() ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn('attribute_group_code'); $filterMock->expects($this->once()) ->method('getValue') ->willReturn($filterValue); @@ -46,20 +43,4 @@ class AttributeGroupCodeFilterTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); } - - public function testApplyIdle() - { - $filterMock = $this->getMockBuilder(Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn(null); - - $collectionMock = $this->getMockBuilder(AbstractDb::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); - } } diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php deleted file mode 100644 index 6291ee629f5..00000000000 --- a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeIdFilterTest.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Eav\Test\Unit\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor; - -use Magento\Eav\Api\Data\AttributeInterface; -use Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeIdFilter; -use Magento\Framework\Api\Filter; -use Magento\Framework\Data\Collection\AbstractDb; - -class AttributeIdFilterTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var AttributeIdFilter - */ - private $filter; - - protected function setUp() - { - $this->filter = new AttributeIdFilter(); - } - - public function testApply() - { - $filterValue = 'filter_value'; - - $filterMock = $this->getMockBuilder(Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filterMock->expects($this->exactly(2)) - ->method('getField') - ->willReturn(AttributeInterface::ATTRIBUTE_ID); - $filterMock->expects($this->once()) - ->method('getValue') - ->willReturn($filterValue); - $filterMock->expects($this->once()) - ->method('getConditionType') - ->willReturn(null); - - $collectionMock = $this->getMockBuilder(AbstractDb::class) - ->disableOriginalConstructor() - ->setMethods(['addFieldToFilter']) - ->getMockForAbstractClass(); - $collectionMock->expects($this->once()) - ->method('addFieldToFilter') - ->with('main_table.' . AttributeInterface::ATTRIBUTE_ID, ['eq' => $filterValue]) - ->willReturnSelf(); - - $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); - } - - public function testApplyIdle() - { - $filterMock = $this->getMockBuilder(Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn(null); - - $collectionMock = $this->getMockBuilder(AbstractDb::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(); - - $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); - } -} diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php index f5170b3b090..856c24cea79 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php @@ -52,9 +52,6 @@ class EntityTypeCodeFilterTest extends \PHPUnit_Framework_TestCase $filterMock = $this->getMockBuilder(Filter::class) ->disableOriginalConstructor() ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn('entity_type_code'); $filterMock->expects($this->once()) ->method('getValue') ->willReturn($filterValue); @@ -69,20 +66,4 @@ class EntityTypeCodeFilterTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); } - - public function testApplyIdle() - { - $filterMock = $this->getMockBuilder(Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn(null); - - $collectionMock = $this->getMockBuilder(Collection::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); - } } diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php index c09b5716658..0f3611b7636 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php @@ -28,9 +28,6 @@ class AttributeGroupAttributeSetIdFilterTest extends \PHPUnit_Framework_TestCase $filterMock = $this->getMockBuilder(Filter::class) ->disableOriginalConstructor() ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn('attribute_set_id'); $filterMock->expects($this->once()) ->method('getValue') ->willReturn($filterValue); @@ -45,20 +42,4 @@ class AttributeGroupAttributeSetIdFilterTest extends \PHPUnit_Framework_TestCase $this->assertTrue($this->filter->apply($filterMock, $collectionMock)); } - - public function testApplyIdle() - { - $filterMock = $this->getMockBuilder(Filter::class) - ->disableOriginalConstructor() - ->getMock(); - $filterMock->expects($this->once()) - ->method('getField') - ->willReturn(null); - - $collectionMock = $this->getMockBuilder(Collection::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->assertFalse($this->filter->apply($filterMock, $collectionMock)); - } } diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index 7ac08c4aee6..774fdb99622 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -91,25 +91,9 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> - <arguments> - <argument name="customFilters" xsi:type="array"> - <item name="attribute_id" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeIdFilter</item> - </argument> - </arguments> - </virtualType> - <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> - <arguments> - <argument name="processors" xsi:type="array"> - <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeFilterProcessor</item> - <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> - <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> - </argument> - </arguments> - </virtualType> <type name="Magento\Eav\Model\AttributeRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite</argument> </arguments> </type> <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeSetFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> @@ -135,6 +119,9 @@ </type> <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="attribute_group_code" xsi:type="string">main_table.attribute_group_code</item> + </argument> <argument name="customFilters" xsi:type="array"> <item name="attribute_set_id" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeGroupAttributeSetIdFilter</item> <item name="attribute_group_code" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor\AttributeGroupCodeFilter</item> @@ -143,6 +130,9 @@ </virtualType> <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupSortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> <arguments> + <argument name="fieldMapping" xsi:type="array"> + <item name="attribute_group_code" xsi:type="string">main_table.attribute_group_code</item> + </argument> <argument name="defaultOrders" xsi:type="array"> <item name="sort_order" xsi:type="string">ASC</item> </argument> -- GitLab From 4d33b2fef91f12227bc4c7a446a892b13bea084d Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Wed, 10 Aug 2016 12:54:49 +0300 Subject: [PATCH 241/838] MAGETWO-56082: SearchCriteria Unified Processing for Sales modules --- .../Command/CaptureStrategyCommand.php | 25 +++++++++++++------ .../Command/CaptureStrategyCommandTest.php | 2 +- .../Request/VaultCaptureDataBuilderTest.php | 2 +- .../Order/Payment/Transaction/Repository.php | 7 +++--- .../Payment/Transaction/RepositoryTest.php | 4 +-- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php b/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php index 3119042b776..a03546b3660 100644 --- a/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php +++ b/app/code/Magento/Braintree/Gateway/Command/CaptureStrategyCommand.php @@ -166,16 +166,25 @@ class CaptureStrategyCommand implements CommandInterface */ private function isExistsCaptureTransaction(OrderPaymentInterface $payment) { - $filters[] = $this->filterBuilder->setField('payment_id') - ->setValue($payment->getId()) - ->create(); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder + ->setField('payment_id') + ->setValue($payment->getId()) + ->create(), + ] + ); - $filters[] = $this->filterBuilder->setField('txn_type') - ->setValue(TransactionInterface::TYPE_CAPTURE) - ->create(); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder + ->setField('txn_type') + ->setValue(TransactionInterface::TYPE_CAPTURE) + ->create(), + ] + ); - $searchCriteria = $this->searchCriteriaBuilder->addFilters($filters) - ->create(); + $searchCriteria = $this->searchCriteriaBuilder->create(); $count = $this->transactionRepository->getList($searchCriteria)->getTotalCount(); return (boolean) $count; diff --git a/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php b/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php index fda3e85d167..9665afa1f36 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php @@ -374,7 +374,7 @@ class CaptureStrategyCommandTest extends \PHPUnit_Framework_TestCase ->willReturnSelf(); $searchCriteria = new SearchCriteria(); - $this->searchCriteriaBuilder->expects(static::once()) + $this->searchCriteriaBuilder->expects(static::exactly(2)) ->method('addFilters') ->willReturnSelf(); $this->searchCriteriaBuilder->expects(static::once()) 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 a5d89fb0e23..165bc94aa68 100644 --- a/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Gateway/Request/VaultCaptureDataBuilderTest.php @@ -80,7 +80,7 @@ class VaultCaptureDataBuilderTest extends \PHPUnit_Framework_TestCase $paymentExtension = $this->getMockBuilder(OrderPaymentExtension::class) ->setMethods(['getVaultPaymentToken']) ->disableOriginalConstructor() - ->getMock(); + ->getMockForAbstractClass(); $paymentToken = $this->getMockBuilder(PaymentToken::class) ->disableOriginalConstructor() diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php index c9743805ac1..c6dc2ceb9e8 100644 --- a/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php +++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction/Repository.php @@ -124,11 +124,11 @@ class Repository implements TransactionRepositoryInterface $cacheStorage = 'txn_type'; $entity = $this->entityStorage->getByIdentifyingFields($identityFieldsForCache, $cacheStorage); if (!$entity) { - $filters[] = $this->filterBuilder + $typeFilter = $this->filterBuilder ->setField(TransactionInterface::TXN_TYPE) ->setValue($transactionType) ->create(); - $filters[] = $this->filterBuilder + $idFilter = $this->filterBuilder ->setField(TransactionInterface::PAYMENT_ID) ->setValue($paymentId) ->create(); @@ -143,7 +143,8 @@ class Repository implements TransactionRepositoryInterface $entity = current( $this->getList( $this->searchCriteriaBuilder - ->addFilters($filters) + ->addFilters([$typeFilter]) + ->addFilters([$idFilter]) ->addSortOrder($transactionIdSort) ->addSortOrder($createdAtSort) ->create() diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php index 4ee404b064f..4445317f31d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Payment/Transaction/RepositoryTest.php @@ -390,9 +390,9 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase $transactionIdSort, $createdAtSort ); - $this->searchCriteriaBuilder->expects($this->once()) + $this->searchCriteriaBuilder->expects($this->exactly(2)) ->method('addFilters') - ->with([$this->filter, $this->filter]) + ->with([$this->filter]) ->willReturnSelf(); $this->searchCriteriaBuilder->expects($this->exactly(2)) ->method('addSortOrder') -- GitLab From 078376ac40a006612fa4d72c0357e0b3a028848f Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Wed, 10 Aug 2016 12:55:28 +0300 Subject: [PATCH 242/838] MAGETWO-56083: SearchCriteria Unified Processing for Vault --- .../Ui/Adminhtml/TokensConfigProvider.php | 65 ++++++++++++------- .../Ui/Adminhtml/TokensConfigProviderTest.php | 12 +++- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php b/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php index c4f31a771c7..5c3ba3d6ed2 100644 --- a/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php +++ b/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php @@ -130,38 +130,57 @@ final class TokensConfigProvider } if ($customerId) { - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::CUSTOMER_ID) - ->setValue($customerId) - ->create(); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder->setField(PaymentTokenInterface::CUSTOMER_ID) + ->setValue($customerId) + ->create(), + ] + ); } else { try { - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::ENTITY_ID) - ->setValue($this->getPaymentTokenEntityId()) - ->create(); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder->setField(PaymentTokenInterface::ENTITY_ID) + ->setValue($this->getPaymentTokenEntityId()) + ->create(), + ] + ); } catch (InputException $e) { return $result; } catch (NoSuchEntityException $e) { return $result; } } - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::PAYMENT_METHOD_CODE) - ->setValue($vaultProviderCode) - ->create(); - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::IS_ACTIVE) - ->setValue(1) - ->create(); - $filters[] = $this->filterBuilder->setField(PaymentTokenInterface::EXPIRES_AT) - ->setConditionType('gt') - ->setValue( - $this->dateTimeFactory->create( - 'now', - new \DateTimeZone('UTC') - )->format('Y-m-d 00:00:00') - ) - ->create(); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder->setField(PaymentTokenInterface::PAYMENT_METHOD_CODE) + ->setValue($vaultProviderCode) + ->create(), + ] + ); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder->setField(PaymentTokenInterface::IS_ACTIVE) + ->setValue(1) + ->create(), + ] + ); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder->setField(PaymentTokenInterface::EXPIRES_AT) + ->setConditionType('gt') + ->setValue( + $this->dateTimeFactory->create( + 'now', + new \DateTimeZone('UTC') + )->format('Y-m-d 00:00:00') + ) + ->create(), + ] + ); - $searchCriteria = $this->searchCriteriaBuilder->addFilters($filters) - ->create(); + $searchCriteria = $this->searchCriteriaBuilder->create(); foreach ($this->paymentTokenRepository->getList($searchCriteria)->getItems() as $token) { $result[] = $componentProvider->getComponentForToken($token); diff --git a/app/code/Magento/Vault/Test/Unit/Model/Ui/Adminhtml/TokensConfigProviderTest.php b/app/code/Magento/Vault/Test/Unit/Model/Ui/Adminhtml/TokensConfigProviderTest.php index ab825de32c9..38948b004ee 100644 --- a/app/code/Magento/Vault/Test/Unit/Model/Ui/Adminhtml/TokensConfigProviderTest.php +++ b/app/code/Magento/Vault/Test/Unit/Model/Ui/Adminhtml/TokensConfigProviderTest.php @@ -572,10 +572,16 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase ->with('gt') ->willReturnSelf(); - $this->searchCriteriaBuilder->expects(self::once()) + $this->searchCriteriaBuilder->expects(self::exactly(4)) ->method('addFilters') - ->with([$customerFilter, $codeFilter, $expiresAtFilter, $isActiveFilter]) - ->willReturnSelf(); + ->willReturnMap( + [ + [$customerFilter, $this->searchCriteriaBuilder], + [$codeFilter, $this->searchCriteriaBuilder], + [$expiresAtFilter, $this->searchCriteriaBuilder], + [$isActiveFilter, $this->searchCriteriaBuilder], + ] + ); $this->searchCriteriaBuilder->expects(self::once()) ->method('create') -- GitLab From 8a1f8d9f4880fa81eeb3d08c448bdb5f740f51a9 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Wed, 10 Aug 2016 13:26:08 +0300 Subject: [PATCH 243/838] MAGETWO-56083: SearchCriteria Unified Processing for Vault --- .../Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php b/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php index 5c3ba3d6ed2..98e7728f732 100644 --- a/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php +++ b/app/code/Magento/Vault/Model/Ui/Adminhtml/TokensConfigProvider.php @@ -205,7 +205,7 @@ final class TokensConfigProvider /** * Get active vault payment by code - * @param $vaultPaymentCode + * @param string $vaultPaymentCode * @return VaultPaymentInterface|null */ private function getVaultPayment($vaultPaymentCode) -- GitLab From 95a109f6e44fbcea8ac0489ee84736fd0c912cfd Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 10 Aug 2016 13:28:45 +0300 Subject: [PATCH 244/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Tax/etc/di.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 8ae648a6294..28d47ca7c6f 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -87,24 +87,24 @@ </type> <type name="Magento\Tax\Model\TaxRuleRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessorComposite</argument> </arguments> </type> <type name="Magento\Tax\Model\Calculation\RateRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessorComposite</argument> </arguments> </type> - <virtualType name="Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> <arguments> <argument name="processors" xsi:type="array"> - <item name="filters" xsi:type="object">Magento\Tax\Model\TaxRate\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> + <item name="filters" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRateFilterProcessor</item> <item name="sorting" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\TaxRate\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <virtualType name="Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRateFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="fieldMapping" xsi:type="array"> <item name="tax_calculation_rate_id" xsi:type="string">main_table.tax_calculation_rate_id</item> @@ -118,7 +118,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\JoinProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor"> + <virtualType name="Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleJoinProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\JoinProcessor"> <arguments> <argument name="customJoins" xsi:type="array"> <item name="rate.tax_calculation_rate_id" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\JoinProcessor\Rate</item> @@ -136,7 +136,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\SortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> + <virtualType name="Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleSortingProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\SortingProcessor"> <arguments> <argument name="fieldMapping" xsi:type="array"> <item name="id" xsi:type="string">tax_calculation_rule_id</item> @@ -147,7 +147,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\FilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> + <virtualType name="Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="fieldMapping" xsi:type="array"> <item name="id" xsi:type="string">tax_calculation_rule_id</item> @@ -158,12 +158,12 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> <arguments> <argument name="processors" xsi:type="array"> - <item name="joins" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\JoinProcessor</item> - <item name="filters" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> - <item name="sorting" xsi:type="object">Magento\Tax\Model\Rule\Api\SearchCriteria\CollectionProcessor\SortingProcessor</item> + <item name="joins" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleJoinProcessor</item> + <item name="filters" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleFilterProcessor</item> + <item name="sorting" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleSortingProcessor</item> <item name="pagination" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\PaginationProcessor</item> </argument> </arguments> -- GitLab From a7a5a41bd0f342502e272b3e5b36f326964e7a7b Mon Sep 17 00:00:00 2001 From: Sergey Semenov <ssemenov@magento.com> Date: Wed, 10 Aug 2016 13:46:40 +0300 Subject: [PATCH 245/838] MAGETWO-56079: SearchCriteria Unified Processing for Cms, Customer and Eav modules --- .../ResourceModel/AddressRepositoryTest.php | 1 + .../Eav/Model/Attribute/GroupRepository.php | 24 +------ .../Magento/Eav/Model/AttributeRepository.php | 31 +-------- ...ttributeGroupAttributeSetIdFilterTest.php} | 0 .../AttributeSetEntityTypeCodeFilterTest.php | 2 +- .../Model/Attribute/GroupRepositoryTest.php | 1 + .../Unit/Model/AttributeRepositoryTest.php | 67 ++++++++++++++----- 7 files changed, 58 insertions(+), 68 deletions(-) rename app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/{AttributeSetIdFilterTest.php => AttributeGroupAttributeSetIdFilterTest.php} (100%) diff --git a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php index 39845e576ab..b72a5f6a417 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/ResourceModel/AddressRepositoryTest.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ namespace Magento\Customer\Test\Unit\Model\ResourceModel; + use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** diff --git a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php index 37d22c1d0fc..da3426d6cf3 100644 --- a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php +++ b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -11,6 +10,9 @@ use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Exception\StateException; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterface { /** @@ -200,26 +202,6 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf return null; } - /** - * Retrieve attribute group code - * - * @deprecated - * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria - * @return null|string - */ - private function retrieveAttributeGroupCodeFromSearchCriteria( - \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria - ) { - foreach ($searchCriteria->getFilterGroups() as $group) { - foreach ($group->getFilters() as $filter) { - if ($filter->getField() === 'attribute_group_code') { - return $filter->getValue(); - } - } - } - return null; - } - /** * Retrieve collection processor * diff --git a/app/code/Magento/Eav/Model/AttributeRepository.php b/app/code/Magento/Eav/Model/AttributeRepository.php index 29b3ca10e70..0894db43bb7 100644 --- a/app/code/Magento/Eav/Model/AttributeRepository.php +++ b/app/code/Magento/Eav/Model/AttributeRepository.php @@ -1,12 +1,12 @@ <?php /** - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Eav\Model; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection; +use Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; @@ -191,33 +191,6 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa return true; } - /** - * Helper function that adds a FilterGroup to the collection. - * - * @deprecated - * @param \Magento\Framework\Api\Search\FilterGroup $filterGroup - * @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection $collection - * @return void - * @throws \Magento\Framework\Exception\InputException - */ - private function addFilterGroupToCollection( - \Magento\Framework\Api\Search\FilterGroup $filterGroup, - Collection $collection - ) { - foreach ($filterGroup->getFilters() as $filter) { - $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; - $field = $filter->getField(); - // Prevent ambiguity during filtration - if ($field == \Magento\Eav\Api\Data\AttributeInterface::ATTRIBUTE_ID) { - $field = 'main_table.' . $field; - } - $collection->addFieldToFilter( - $field, - [$condition => $filter->getValue()] - ); - } - } - /** * Retrieve collection processor * @@ -228,7 +201,7 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite' + CollectionProcessorComposite::class ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilterTest.php similarity index 100% rename from app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetIdFilterTest.php rename to app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeGroupAttributeSetIdFilterTest.php diff --git a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php index 856c24cea79..7bc9706b324 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Api/SearchCriteria/CollectionProcessor/FilterProcessor/AttributeSetEntityTypeCodeFilterTest.php @@ -11,7 +11,7 @@ use Magento\Eav\Model\Entity\Type; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection; use Magento\Framework\Api\Filter; -class EntityTypeCodeFilterTest extends \PHPUnit_Framework_TestCase +class AttributeSetEntityTypeCodeFilterTest extends \PHPUnit_Framework_TestCase { /** * @var AttributeSetEntityTypeCodeFilter diff --git a/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php index 76fc8f8b02a..2d9eb22cfd9 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Attribute/GroupRepositoryTest.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ namespace Magento\Eav\Test\Unit\Model\Attribute; + use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; /** diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php index cdb71a55b9c..e6d9ce9de9e 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php @@ -6,11 +6,15 @@ namespace Magento\Eav\Test\Unit\Model; use Magento\Eav\Api\Data\AttributeSearchResultsInterfaceFactory; +use Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection; use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase { /** @@ -119,20 +123,9 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase $searchCriteriaMock = $this->getMockBuilder(SearchCriteriaInterface::class) ->getMockForAbstractClass(); - $attributeMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeInterface::class) - ->setMethods([ - 'getAttributeCode', - 'getAttributeId', - ]) - ->getMockForAbstractClass(); - $attributeMock->expects($this->once()) - ->method('getAttributeCode') - ->willReturn($attributeCode); - $attributeMock->expects($this->once()) - ->method('getAttributeId') - ->willReturn($attributeId); + $attributeMock = $this->createAttributeMock($attributeCode, $attributeId); - $attributeCollectionMock = $this->getMockBuilder(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection::class) + $attributeCollectionMock = $this->getMockBuilder(Collection::class) ->disableOriginalConstructor() ->getMock(); $attributeCollectionMock->expects($this->once()) @@ -209,8 +202,27 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase ->with($searchCriteriaMock, $attributeCollectionMock) ->willReturnSelf(); + $searchResultsMock = $this->createSearchResultsMock($searchCriteriaMock, $attributeMock, $collectionSize); + + $this->searchResultsFactory->expects($this->once()) + ->method('create') + ->willReturn($searchResultsMock); + + $this->assertEquals($searchResultsMock, $this->model->getList($entityTypeCode, $searchCriteriaMock)); + } + + /** + * @param \PHPUnit_Framework_MockObject_MockObject $searchCriteriaMock + * @param \PHPUnit_Framework_MockObject_MockObject $attributeMock + * @param int $collectionSize + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function createSearchResultsMock($searchCriteriaMock, $attributeMock, $collectionSize) + { + /** @var \PHPUnit_Framework_MockObject_MockObject $searchResultsMock */ $searchResultsMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSearchResultsInterface::class) ->getMockForAbstractClass(); + $searchResultsMock->expects($this->once()) ->method('setSearchCriteria') ->with($searchCriteriaMock) @@ -224,10 +236,31 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase ->with($collectionSize) ->willReturnSelf(); - $this->searchResultsFactory->expects($this->once()) - ->method('create') - ->willReturn($searchResultsMock); + return $searchResultsMock; + } - $this->assertEquals($searchResultsMock, $this->model->getList($entityTypeCode, $searchCriteriaMock)); + /** + * @param string $attributeCode + * @param int $attributeId + * @return \PHPUnit_Framework_MockObject_MockObject + */ + protected function createAttributeMock($attributeCode, $attributeId) + { + /** @var \PHPUnit_Framework_MockObject_MockObject $attributeMock */ + $attributeMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeInterface::class) + ->setMethods([ + 'getAttributeCode', + 'getAttributeId', + ]) + ->getMockForAbstractClass(); + + $attributeMock->expects($this->once()) + ->method('getAttributeCode') + ->willReturn($attributeCode); + $attributeMock->expects($this->once()) + ->method('getAttributeId') + ->willReturn($attributeId); + + return $attributeMock; } } -- GitLab From 2d242efe1b0eac90b9bffb602fb48638f70f1877 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Wed, 10 Aug 2016 14:03:59 +0300 Subject: [PATCH 246/838] MAGETWO-56008: Moving getStoreByWebsite to Store Module --- app/code/Magento/Store/Model/StoreManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/StoreManager.php b/app/code/Magento/Store/Model/StoreManager.php index 6f68da6eb07..c34f4e1bd2a 100644 --- a/app/code/Magento/Store/Model/StoreManager.php +++ b/app/code/Magento/Store/Model/StoreManager.php @@ -295,7 +295,7 @@ class StoreManager implements * @deprecated * @return StoreWebsiteRelation */ - public function getStoreWebsiteRelation() + private function getStoreWebsiteRelation() { return ObjectManager::getInstance()->get(StoreWebsiteRelation::class); } -- GitLab From d425d25c137a19261dd55acd5092146b38598abf Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 10 Aug 2016 14:53:36 +0300 Subject: [PATCH 247/838] MAGETWO-56677: Create template and components for notification area --- .../view/adminhtml/web/js/grid/columns/message.js | 4 +++- .../view/adminhtml/web/template/grid/cells/message.html | 2 +- .../view/adminhtml/web/template/grid/listing.html | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js index 0f3920051cd..794a9206324 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js @@ -17,11 +17,13 @@ define([ } }, + /** @inheritdoc */ getLabel: function (record) { return record[this.messageIndex]; }, - getFieldClasses: function ($row) { + /** @inheritdoc */ + getFieldClass: function ($row) { var status = $row.status || 'info'; this.fieldClass['message-' + status] = true; diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html index 171e96858a2..869842e8ee8 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/cells/message.html @@ -4,5 +4,5 @@ * See COPYING.txt for license details. */ --> -<div css="$col.getFieldClasses($row())" +<div css="$col.getFieldClass($row())" html="$col.getLabel($row())"/> \ No newline at end of file diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html index 496e536e82e..ba4396a01b6 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ --> -<div id="system_messages" class="message-system<?php if ($lastCritical): ?> message-system-unread<?php endif; ?>"> +<div id="system_messages" class="message-system"> <div class="message-system-inner" data-bind="collapsible"> <div class="message-system-short"> <button data-bind="toggleCollapsible" class="message-system-action-dropdown"> -- GitLab From 33bfbda7613e948a14985e24d0c1ec2b8b24288e Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Wed, 10 Aug 2016 14:58:17 +0300 Subject: [PATCH 248/838] MAGETWO-56493: Introduce and implement OrderRegisterInterface --- .../Model/Order/Shipment/OrderRegistrar.php | 28 +++++++ .../Shipment/OrderRegistrarInterface.php | 26 +++++++ .../Order/Shipment/OrderRegistrarTest.php | 73 +++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 3 +- 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrar.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php create mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/OrderRegistrarTest.php diff --git a/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrar.php b/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrar.php new file mode 100644 index 00000000000..040ab12949b --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrar.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentInterface; + +class OrderRegistrar implements \Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface +{ + /** + * @param OrderInterface $order + * @param ShipmentInterface $shipment + * @return OrderInterface + */ + public function register(OrderInterface $order, ShipmentInterface $shipment) + { + /** @var \Magento\Sales\Api\Data\ShipmentItemInterface|\Magento\Sales\Model\Order\Shipment\Item $item */ + foreach ($shipment->getItems() as $item) { + if ($item->getQty() > 0) { + $item->register(); + } + } + return $order; + } +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php new file mode 100644 index 00000000000..6131b3585bc --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentInterface; + +/** + * Interface OrderRegistrarInterface + * + * Calculate order shipped data based on created shipment + * + * @api + */ +interface OrderRegistrarInterface +{ + /** + * @param OrderInterface $order + * @param ShipmentInterface $invoice + * @return OrderInterface + */ + public function register(OrderInterface $order, ShipmentInterface $invoice); +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/OrderRegistrarTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/OrderRegistrarTest.php new file mode 100644 index 00000000000..e5bff791edc --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/OrderRegistrarTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Order\Shipment; + +class OrderRegistrarTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Model\Order\Shipment\OrderRegistrar + */ + private $model; + + /** + * @var \Magento\Sales\Api\Data\OrderInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var \Magento\Sales\Api\Data\ShipmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentMock; + + protected function setUp() + { + $this->orderMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->shipmentMock = $this->getMockBuilder(\Magento\Sales\Api\Data\ShipmentInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->model = new \Magento\Sales\Model\Order\Shipment\OrderRegistrar(); + } + + public function testRegister() + { + $item1 = $this->getShipmentItemMock(); + $item1->expects($this->once()) + ->method('getQty') + ->willReturn(0); + $item1->expects($this->never()) + ->method('register'); + + $item2 = $this->getShipmentItemMock(); + $item2->expects($this->once()) + ->method('getQty') + ->willReturn(0.5); + $item2->expects($this->once()) + ->method('register'); + + $items = [$item1, $item2]; + $this->shipmentMock->expects($this->once()) + ->method('getItems') + ->willReturn($items); + $this->assertEquals( + $this->orderMock, + $this->model->register($this->orderMock, $this->shipmentMock) + ); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getShipmentItemMock() + { + return $this->getMockBuilder(\Magento\Sales\Api\Data\ShipmentItemInterface::class) + ->disableOriginalConstructor() + ->setMethods(['register']) + ->getMockForAbstractClass(); + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index a6c84816dd3..89594620b09 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -67,10 +67,11 @@ <preference for="Magento\Sales\Api\TransactionRepositoryInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Repository"/> <preference for="Magento\Sales\Model\Order\Invoice\NotifierInterface" type="Magento\Sales\Model\Order\Invoice\Notifier"/> <preference for="Magento\Sales\Model\Order\InvoiceValidatorInterface" type="Magento\Sales\Model\Order\InvoiceValidator"/> - <preference for="Magento\Sales\Model\Order\PaymentAdapterInterface" type="Magento\Sales\Model\Order\PaymentAdapter"/> <preference for="Magento\Sales\Model\Order\OrderValidatorInterface" type="Magento\Sales\Model\Order\OrderValidator"/> + <preference for="Magento\Sales\Model\Order\PaymentAdapterInterface" type="Magento\Sales\Model\Order\PaymentAdapter"/> <preference for="Magento\Sales\Model\Order\Payment\Transaction\ManagerInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Manager"/> <preference for="Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Builder"/> + <preference for="Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface" type="Magento\Sales\Model\Order\Shipment\OrderRegistrar"/> <preference for="Magento\Sales\Model\Spi\CreditmemoCommentResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Creditmemo\Comment"/> <preference for="Magento\Sales\Model\Spi\CreditmemoItemResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Creditmemo\Item"/> <preference for="Magento\Sales\Model\Spi\CreditmemoResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Creditmemo"/> -- GitLab From 9f1be3693e992fee1d48e8101bdcb55571e56bfd Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Wed, 10 Aug 2016 16:40:22 +0300 Subject: [PATCH 249/838] MAGETWO-55193: Extension Management with Marketplace data - Add component title, type and link from Marketplace --- .../web/app/setup/styles/less/_setup.less | 2 +- .../styles/less/components/_data-grid.less | 20 +++ setup/pub/styles/setup.css | 2 +- .../Setup/Controller/InstallExtensionGrid.php | 7 +- .../Magento/Setup/Model/Grid/Extension.php | 6 +- setup/src/Magento/Setup/Model/Grid/Module.php | 137 ++++++++++++------ .../src/Magento/Setup/Model/PackagesData.php | 15 ++ .../Controller/UpdateExtensionGridTest.php | 1 + .../Test/Unit/Model/Grid/ExtensionTest.php | 2 + .../Setup/Test/Unit/Model/Grid/ModuleTest.php | 27 +++- .../Test/Unit/Model/PackagesDataTest.php | 11 +- setup/view/magento/setup/extension-grid.phtml | 2 +- .../setup/install-extension-grid.phtml | 7 +- setup/view/magento/setup/module-grid.phtml | 4 +- .../magento/setup/update-extension-grid.phtml | 7 +- 15 files changed, 188 insertions(+), 62 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less index 6392ef60be9..23154cdb878 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less @@ -98,7 +98,7 @@ // Updater pages //@import '../../../updater/styles/less/pages/_common.less'; //@import '../../../updater/styles/less/pages/_home.less'; -//@import '../../../updater/styles/less/pages/_component-manager.less'; +//@import '../../../updater/styles/less/pages/_extension-manager.less'; //@import '../../../updater/styles/less/pages/_login.less'; // diff --git a/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less b/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less index d8d63f09bd1..9e2e7037b0e 100644 --- a/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less +++ b/app/design/adminhtml/Magento/backend/web/app/updater/styles/less/components/_data-grid.less @@ -112,6 +112,26 @@ } } } + + &._tooltip { + background: transparent; + margin: 0px 0px 8px 5px; + + a { + width: 21px; + + &:hover { + text-decoration: none; + } + + &:before { + color: @color-tertiary; + content: @icon-help__content; + font-family: @icons__font-family; + font-size: @component-indicator__size; + } + } + } } .col-manager-item-name { diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css index 4ee5d4979d2..72ad9b834a8 100644 --- a/setup/pub/styles/setup.css +++ b/setup/pub/styles/setup.css @@ -3,4 +3,4 @@ * See COPYING.txt for license details. */ -.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-moz-appearance:none;-webkit-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title,.admin__menu .submenu .parent>a{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-extension>a:before{content:'\e612'}.admin__menu .item-component>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file +.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.component-indicator._tooltip{background:0 0;margin:0 0 8px 5px}.component-indicator._tooltip a{width:21px}.component-indicator._tooltip a:hover{text-decoration:none}.component-indicator._tooltip a:before{color:#514943;content:'\e633';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file diff --git a/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php b/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php index a3f5a9992a3..7ec8ef19b08 100644 --- a/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php +++ b/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php @@ -62,7 +62,12 @@ class InstallExtensionGrid extends AbstractActionController $packages = isset($extensions['packages']) ? $extensions['packages'] : []; array_walk($packages, function (&$package) { $package['vendor'] = ucfirst($package['vendor']); - $package['type'] = $this->typeMapper->map($package['name'], $package['type']); + $package['link'] = isset($package['extra']['x-magento-ext-package-link']) ? + $package['extra']['x-magento-ext-package-link'] : ''; + $package['product_name'] = isset($package['extra']['x-magento-ext-title']) ? + $package['extra']['x-magento-ext-title'] : $package['name']; + $package['type'] = isset($package['extra']['x-magento-ext-type']) ? + $package['extra']['x-magento-ext-type'] : $this->typeMapper->map($package['name'], $package['type']); }); return new JsonModel( diff --git a/setup/src/Magento/Setup/Model/Grid/Extension.php b/setup/src/Magento/Setup/Model/Grid/Extension.php index 8ac59a5244d..2290c89ab15 100644 --- a/setup/src/Magento/Setup/Model/Grid/Extension.php +++ b/setup/src/Magento/Setup/Model/Grid/Extension.php @@ -88,8 +88,12 @@ class Extension private function formatExtensions(array $extensions) { foreach ($extensions as &$extension) { + $extraInfo = $this->packagesData->getPackageExtraInfo($extension['name'], $extension['version']); $extension['vendor'] = ucfirst(current(explode('/', $extension['name']))); - $extension['type'] = $this->typeMapper->map($extension['name'], $extension['type']); + $extension['product_name'] = isset($extraInfo['x-magento-ext-title']) ? + $extraInfo['x-magento-ext-title'] : $extension['name']; + $extension['type'] = isset($extraInfo['x-magento-ext-type']) ? + $extraInfo['x-magento-ext-type'] : $this->typeMapper->map($extension['name'], $extension['type']); } return array_values($extensions); } diff --git a/setup/src/Magento/Setup/Model/Grid/Module.php b/setup/src/Magento/Setup/Model/Grid/Module.php index 269367779e7..2e481638d45 100644 --- a/setup/src/Magento/Setup/Model/Grid/Module.php +++ b/setup/src/Magento/Setup/Model/Grid/Module.php @@ -3,10 +3,14 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Setup\Model\Grid; use Magento\Framework\Composer\ComposerInformation; +use Magento\Framework\Module\FullModuleList; +use Magento\Framework\Module\ModuleList; +use Magento\Framework\Module\PackageInfoFactory; +use Magento\Setup\Model\ObjectManagerProvider; +use Magento\Setup\Model\PackagesData; /** * Module grid @@ -32,21 +36,21 @@ class Module private $packageInfo; /** - * @var \Magento\Setup\Model\ObjectManagerProvider + * @var ObjectManagerProvider */ private $objectManagerProvider; /** * Full Module info * - * @var \Magento\Framework\Module\FullModuleList + * @var FullModuleList */ private $fullModuleList; /** * Module info * - * @var \Magento\Framework\Module\ModuleList + * @var ModuleList */ private $moduleList; @@ -56,25 +60,25 @@ class Module private $typeMapper; /** - * @var \Magento\Setup\Model\PackagesData + * @var PackagesData */ private $packagesData; /** * @param ComposerInformation $composerInformation - * @param \Magento\Framework\Module\FullModuleList $fullModuleList - * @param \Magento\Framework\Module\ModuleList $moduleList - * @param \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider + * @param FullModuleList $fullModuleList + * @param ModuleList $moduleList + * @param ObjectManagerProvider $objectManagerProvider * @param TypeMapper $typeMapper - * @param \Magento\Setup\Model\PackagesData $packagesData + * @param PackagesData $packagesData */ public function __construct( ComposerInformation $composerInformation, - \Magento\Framework\Module\FullModuleList $fullModuleList, - \Magento\Framework\Module\ModuleList $moduleList, - \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider, + FullModuleList $fullModuleList, + ModuleList $moduleList, + ObjectManagerProvider $objectManagerProvider, TypeMapper $typeMapper, - \Magento\Setup\Model\PackagesData $packagesData + PackagesData $packagesData ) { $this->composerInformation = $composerInformation; $this->fullModuleList = $fullModuleList; @@ -92,46 +96,81 @@ class Module public function getList() { $this->packageInfo = $this->objectManagerProvider->get() - ->get(\Magento\Framework\Module\PackageInfoFactory::class) + ->get(PackageInfoFactory::class) ->create(); $items = array_replace_recursive( + $this->getModuleListFromComposer(), + $this->getFullModuleList() + ); + + $items = $this->addRequiredBy($this->addGeneralInfo($items)); + + return $items; + } + + /** + * Get module list from composer + * + * @return array + */ + private function getModuleListFromComposer() + { + return array_filter( $this->composerInformation->getInstalledMagentoPackages(), - $this->getInstalledModules() + function ($item) { + return $item['type'] === ComposerInformation::MODULE_PACKAGE_TYPE; + } ); + } - $items = array_filter($items, function ($item) { - return $item['type'] === ComposerInformation::MODULE_PACKAGE_TYPE; - }); + /** + * Get full module list + * + * @return array + */ + private function getFullModuleList() + { + return $this->getModulesInfo( + $this->fullModuleList->getNames() + ); + } - array_walk($items, function (&$module, $name) { - $module['moduleName'] = $module['moduleName'] ?: $this->packageInfo->getModuleName($name); - $module['enable'] = $this->moduleList->has($module['moduleName']); - $module['vendor'] = ucfirst(current(preg_split('%[/_]%', $name))); - $module['type'] = $this->typeMapper->map($name, $module['type']); - $module['requiredBy'] = $this->getModuleRequiredBy($name); - }); + /** + * Add all modules, extensions, metapackages a module required by + * + * @param array $items + * @return array + */ + private function addRequiredBy(array $items) + { + foreach ($items as $key => $item) { + $items[$key]['requiredBy'] = $item['name'] != self::UNKNOWN_PACKAGE_NAME ? + $this->addGeneralInfo( + $this->getModulesInfo( + $this->packageInfo->getRequiredBy($item['name']) + ) + ) : []; + } - return array_values($items); + return $items; } /** - * Get all modules, extensions, metapackages a module required by - * - * @param string $name Module name + * Get modules info + * + * @param array $moduleList * @return array */ - private function getModuleRequiredBy($name) + private function getModulesInfo(array $moduleList) { $result = []; - $modules = $this->packageInfo->getRequiredBy($name); - foreach ($modules as $moduleName) { + foreach ($moduleList as $moduleName) { $packageName = $this->packageInfo->getPackageName($moduleName); - $result[] = [ + $key = $packageName ?: $moduleName; + $result[$key] = [ 'name' => $packageName ?: self::UNKNOWN_PACKAGE_NAME, 'moduleName' => $moduleName, - 'type' => $this->typeMapper->map($packageName, ComposerInformation::MODULE_PACKAGE_TYPE), - 'enable' => $this->moduleList->has($moduleName), 'version' => $this->packageInfo->getVersion($moduleName) ?: self::UNKNOWN_VERSION, ]; } @@ -140,23 +179,27 @@ class Module } /** - * Get full list of installed modules + * Add general info to result array * + * @param array $items * @return array */ - private function getInstalledModules() + private function addGeneralInfo(array $items) { - $modules = []; - $allModules = $this->fullModuleList->getNames(); - foreach ($allModules as $module) { - $packageName = $this->packageInfo->getPackageName($module); - $name = $packageName ?: $module; - $modules[$name]['name'] = $packageName ?: self::UNKNOWN_PACKAGE_NAME; - $modules[$name]['moduleName'] = $module; - $modules[$name]['type'] = ComposerInformation::MODULE_PACKAGE_TYPE; - $modules[$name]['version'] = $this->packageInfo->getVersion($module) ?: self::UNKNOWN_VERSION; + foreach ($items as &$item) { + $item['moduleName'] = $item['moduleName'] ?: $this->packageInfo->getModuleName($item['name']); + $item['enable'] = $this->moduleList->has($item['moduleName']); + + $vendorSource = $item['name'] == self::UNKNOWN_PACKAGE_NAME ? $item['moduleName'] : $item['name']; + $item['vendor'] = ucfirst(current(preg_split('%[/_]%', $vendorSource))); + + $extraInfo = $this->packagesData->getPackageExtraInfo($item['name'], $item['version']); + $item['product_name'] = isset($extraInfo['x-magento-ext-title']) ? + $extraInfo['x-magento-ext-title'] : $item['name']; + $item['type'] = isset($extraInfo['x-magento-ext-type']) ? $extraInfo['x-magento-ext-type'] : + $this->typeMapper->map($item['name'], ComposerInformation::MODULE_PACKAGE_TYPE); } - return $modules; + return array_values($items); } } diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index 0138212ef39..d608827a529 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -289,6 +289,21 @@ class PackagesData } } + /** + * Get package extra info + * + * @param string $packageName + * @param string $packageVersion + * @return array + */ + public function getPackageExtraInfo($packageName, $packageVersion) + { + $packagesJson = $this->getPackagesJson(); + + return isset($packagesJson[$packageName][$packageVersion]['extra']) ? + $packagesJson[$packageName][$packageVersion]['extra'] : [] ; + } + /** * Check if this new user package * diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/UpdateExtensionGridTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/UpdateExtensionGridTest.php index a76e9bca63c..d67f923b27e 100644 --- a/setup/src/Magento/Setup/Test/Unit/Controller/UpdateExtensionGridTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Controller/UpdateExtensionGridTest.php @@ -50,6 +50,7 @@ class UpdateExtensionGridTest extends \PHPUnit_Framework_TestCase $extensionData = [ [ 'name' => 'magento-package-1', + 'product_name' => 'magento/package-1', 'type' => 'magento2-module', 'version' => '1.0.0', 'latestVersion' => '2.0.5', diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php index 6e2963fd063..49da1fe0976 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php @@ -93,6 +93,7 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase $expected = [ [ 'name' => 'magento/package-1', + 'product_name' => 'magento/package-1', 'type' => 'Extension', 'version' => '1.0.0', 'update' => true, @@ -101,6 +102,7 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase ], [ 'name' => 'magento/package-2', + 'product_name' => 'magento/package-2', 'type' => 'Extension', 'version' => '1.0.1', 'update' => false, diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php index 26df267532f..71121a2140b 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php @@ -155,14 +155,13 @@ class ModuleTest extends \PHPUnit_Framework_TestCase $this->packageInfoMock->expects(static::never()) ->method('getModuleName'); - $this->typeMapperMock->expects(static::exactly(2)) + $this->typeMapperMock->expects(static::once()) ->method('map') ->willReturnMap([ - ['magento/sample-module-one', 'magento2-module', 'Module'], - ['Sample_ModuleTwo', 'magento2-module', 'Module'], + [Module::UNKNOWN_PACKAGE_NAME, 'magento2-module', 'Module'], ]); - $this->packageInfoMock->expects(static::exactly(2)) + $this->packageInfoMock->expects(static::once()) ->method('getRequiredBy') ->willReturn([]); $this->packageInfoMock->expects(static::exactly(2)) @@ -177,6 +176,22 @@ class ModuleTest extends \PHPUnit_Framework_TestCase ['Sample_ModuleOne', '1.0.0'], ['Sample_ModuleTwo', ''], ]); + + $this->packagesDataMock->expects(static::exactly(2)) + ->method('getPackageExtraInfo') + ->willReturnMap([ + [ + 'magento/sample-module-one', + '1.0.0', + [ + 'x-magento-ext-title' => 'Sample Module Full Name', + 'x-magento-ext-type' => 'Extension' + + ] + ], + ]); + + $this->moduleListMock->expects(static::exactly(2)) ->method('has') ->willReturn(true); @@ -187,11 +202,12 @@ class ModuleTest extends \PHPUnit_Framework_TestCase $expected = [ [ 'name' => 'magento/sample-module-one', - 'type' => 'Module', + 'type' => 'Extension', 'version' => '1.0.0', 'vendor' => 'Magento', 'moduleName' => 'Sample_ModuleOne', 'enable' => true, + 'product_name' => 'Sample Module Full Name', 'requiredBy' => [], ], [ @@ -201,6 +217,7 @@ class ModuleTest extends \PHPUnit_Framework_TestCase 'vendor' => 'Sample', 'moduleName' => 'Sample_ModuleTwo', 'enable' => true, + 'product_name' => Module::UNKNOWN_PACKAGE_NAME, 'requiredBy' => [], ], ]; diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php index 35491d3967f..f4e21834a7f 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php @@ -110,7 +110,8 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase . '}, "magento\/package-3":{' . '"1.0.0":{"name":"magento\/package-3","version":"1.0.0","vendor":"test","type":"magento2-module"},' . '"1.0.1":{"name":"magento\/package-3","version":"1.0.1","vendor":"test","type":"magento2-module"},' - . '"1.0.2":{"name":"magento\/package-3","version":"1.0.2","vendor":"test","type":"magento2-module"}' + . '"1.0.2":{"name":"magento\/package-3","version":"1.0.2","vendor":"test","type":"magento2-module",' + . '"extra":{"x-magento-ext-title":"Package 3 title", "x-magento-ext-type":"Extension"}}' . '}}}' ); @@ -163,4 +164,12 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase $this->packagesData->getMetaPackagesMap() ); } + + public function testGetPackageExtraInfo() + { + static::assertEquals( + ['x-magento-ext-title' => 'Package 3 title', 'x-magento-ext-type' => 'Extension'], + $this->packagesData->getPackageExtraInfo('magento/package-3', '1.0.2') + ); + } } diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index 1b181c5bc9b..fc6129ae7f7 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -130,7 +130,7 @@ data-label="{{getIndicatorInfo(extension, 'label')}}" ><span>{{getIndicatorInfo(extension, 'label')}}</span> </span> - <span class="data-grid-data">{{extension.name}}</span> + <span class="data-grid-data">{{extension.product_name}}</span> </td> <td> <span class="data-grid-data">{{extension.type}}</span> diff --git a/setup/view/magento/setup/install-extension-grid.phtml b/setup/view/magento/setup/install-extension-grid.phtml index 04dc3499371..27a3a893cfd 100644 --- a/setup/view/magento/setup/install-extension-grid.phtml +++ b/setup/view/magento/setup/install-extension-grid.phtml @@ -96,7 +96,7 @@ </label> </td> <td> - <span class="data-grid-data">{{extension.name}}</span> + <span class="data-grid-data">{{extension.product_name}}</span> </td> <td> <span class="data-grid-data">{{extension.type}}</span> @@ -111,6 +111,11 @@ value="{{version}}">Version {{version}}</option> </select> </span> + <span class="component-indicator _tooltip" + ng-show="extension.link" + data-label="View info on Marketplace" + ><a href="{{extension.link}}" target="_blank"></a> + </span> </td> <td class="data-grid-data"> <div class="action-wrap" ng-class="_active"> diff --git a/setup/view/magento/setup/module-grid.phtml b/setup/view/magento/setup/module-grid.phtml index f6b3e6ae5d7..b310aef76c9 100644 --- a/setup/view/magento/setup/module-grid.phtml +++ b/setup/view/magento/setup/module-grid.phtml @@ -78,7 +78,7 @@ ng-class="{'_show-dependencies': item.requiredBy.length > 0 && showDependencies, '_hide-dependencies': item.requiredBy.length > 0 && !showDependencies, '_no-dependencies': item.requiredBy.length == 0}"> - {{item.name}} + {{item.product_name}} </div> <div class="product-modules-block" ng-show="item.requiredBy.length > 0 && showDependencies"> <div class="product-modules-title"> @@ -94,7 +94,7 @@ data-label="{{getIndicatorInfo(product, 'label')}}"> <span>{{getIndicatorInfo(product, 'label')}}</span> </span> - {{product.name}} + {{product.product_name}} </li> </ul> </div> diff --git a/setup/view/magento/setup/update-extension-grid.phtml b/setup/view/magento/setup/update-extension-grid.phtml index 2c8625a82ed..e308a63b048 100644 --- a/setup/view/magento/setup/update-extension-grid.phtml +++ b/setup/view/magento/setup/update-extension-grid.phtml @@ -59,7 +59,7 @@ | startFrom:(currentPage - 1) * rowLimit | limitTo:rowLimit" > <td> - <span class="data-grid-data">{{extension.name}}</span> + <span class="data-grid-data">{{extension.product_name}}</span> </td> <td> <span class="data-grid-data">{{extension.type}}</span> @@ -78,6 +78,11 @@ >Version {{version}}</option> </select> </span> + <span class="component-indicator _tooltip" + ng-show="extension.link" + data-label="View info on Marketplace" + ><a href="{{extension.link}}" target="_blank"></a> + </span> </td> <td class="data-grid-data"> <div class="action-wrap" ng-class="_active"> -- GitLab From 522b5cdeb1ab94e9ef5a93ba1855e3fb77b7a897 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Wed, 10 Aug 2016 17:13:21 +0300 Subject: [PATCH 250/838] MAGETWO-56743: Unable to upgrade with split databases --- .../Magento/Framework/Module/Test/Unit/SetupTest.php | 6 +++++- setup/src/Magento/Setup/Test/Unit/Module/SetupTest.php | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/SetupTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/SetupTest.php index 63b5d54e2e7..984c9a073fb 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/SetupTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/SetupTest.php @@ -34,7 +34,11 @@ class SetupTest extends \PHPUnit_Framework_TestCase $this->resourceModel->expects($this->any()) ->method('getConnection') ->with(self::CONNECTION_NAME) - ->will($this->returnValue($this->connection)); + ->willReturn($this->connection); + $this->resourceModel->expects($this->any()) + ->method('getConnectionByName') + ->with(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION) + ->willReturn($this->connection); $this->object = new Setup($this->resourceModel, self::CONNECTION_NAME); } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/SetupTest.php b/setup/src/Magento/Setup/Test/Unit/Module/SetupTest.php index 231adb9ab69..9a75c0a3d4b 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/SetupTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/SetupTest.php @@ -30,6 +30,10 @@ class SetupTest extends \PHPUnit_Framework_TestCase ->method('getConnection') ->with(self::CONNECTION_NAME) ->will($this->returnValue($this->connection)); + $resourceModel->expects($this->any()) + ->method('getConnectionByName') + ->with(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION) + ->willReturn($this->connection); $this->setup = new Setup($resourceModel, self::CONNECTION_NAME); } -- GitLab From 7eeec1e406beb7b2237e885aa94bcd2f21fda499 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Wed, 10 Aug 2016 17:34:44 +0300 Subject: [PATCH 251/838] MAGETWO-55193: Extension Management with Marketplace data - Add extension link field to Extension model --- .../src/Magento/Setup/Model/Grid/Extension.php | 2 ++ .../Test/Unit/Model/Grid/ExtensionTest.php | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Model/Grid/Extension.php b/setup/src/Magento/Setup/Model/Grid/Extension.php index 2290c89ab15..d02c78b7bf9 100644 --- a/setup/src/Magento/Setup/Model/Grid/Extension.php +++ b/setup/src/Magento/Setup/Model/Grid/Extension.php @@ -94,6 +94,8 @@ class Extension $extraInfo['x-magento-ext-title'] : $extension['name']; $extension['type'] = isset($extraInfo['x-magento-ext-type']) ? $extraInfo['x-magento-ext-type'] : $this->typeMapper->map($extension['name'], $extension['type']); + $extension['link'] = isset($extraInfo['x-magento-ext-package-link']) ? + $extraInfo['x-magento-ext-package-link'] : ''; } return array_values($extensions); } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php index 49da1fe0976..fd02a3b402f 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php @@ -90,6 +90,19 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase ] ); + $this->packagesDataMock->expects($this->exactly(2)) + ->method('getPackageExtraInfo') + ->willReturnMap( + [ + ['magento/package-1', '1.0.0', []], + [ + 'magento/package-2', + '1.0.1', + ['x-magento-ext-title'=> 'Package2 title', 'x-magento-ext-package-link' => 'http://test.de'] + ], + ] + ); + $expected = [ [ 'name' => 'magento/package-1', @@ -99,15 +112,17 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase 'update' => true, 'uninstall' => true, 'vendor' => 'Magento', + 'link' => '', ], [ 'name' => 'magento/package-2', - 'product_name' => 'magento/package-2', + 'product_name' => 'Package2 title', 'type' => 'Extension', 'version' => '1.0.1', 'update' => false, 'uninstall' => true, 'vendor' => 'Magento', + 'link' => 'http://test.de', ], ]; -- GitLab From 1103b06b16823f093721df330c485f7f45e6d9dd Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 09:48:32 -0500 Subject: [PATCH 252/838] MAGETWO-55925: Eliminate @escapeNotVerified in CatalogWidget Module Applying escape functions in templates --- .../view/adminhtml/templates/product/widget/conditions.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml index f5f2b898a97..9f52576db7f 100644 --- a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml +++ b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml @@ -33,6 +33,6 @@ $fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' "Magento_Rule/rules", "prototype" ], function(VarienRulesForm){ - window.<?php echo $block->escapeJs($block->getHtmlId()) ?> = new VarienRulesForm('<?php echo $block->escapeJs($block->getHtmlId()) ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); + window.<?php echo $block->escapeHtml($block->getHtmlId()) ?> = new VarienRulesForm('<?php echo $block->escapeHtml($block->getHtmlId()) ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); }); </script> -- GitLab From e7db0dac5f62b690c4f02233b4960a1156b2711a Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 09:53:50 -0500 Subject: [PATCH 253/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module Applying escape functions in templates --- .../Cms/view/adminhtml/templates/browser/content/uploader.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ced0a905412..1272936ec7a 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 @@ -39,7 +39,7 @@ require([ }, sequentialUploads: true, acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - maxFileSize: <?php echo $block->escapeJs($block->getFileSizeService()->getMaxFileSize()) ?> , + maxFileSize: <?php echo $block->escapeHtml($block->getFileSizeService()->getMaxFileSize()) ?> , add: function (e, data) { var progressTmpl = mageTemplate('#<?php echo $block->getHtmlId(); ?>-template'), fileSize, -- GitLab From 4b37e4ef959de654b82c9edc6cd918289dfb7ba1 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 10:15:29 -0500 Subject: [PATCH 254/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module Applying escape functions in templates --- .../catalog/category/widget/tree.phtml | 18 +++--- .../templates/instance/edit/layout.phtml | 59 ++++++++++--------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml index 32c7486d867..8ec14aff1db 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -14,7 +14,7 @@ <script> require(['jquery', "prototype", "extjs/ext-tree-checkbox"], function(jQuery){ -var tree<?php echo $block->escapeJs($block->getId()) ?>; +var tree<?php echo $block->escapeHtml($block->getId()) ?>; var useMassaction = <?php /* @noEscape */ echo $block->getUseMassaction() ? 1 : 0; ?>; @@ -43,7 +43,7 @@ Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { if (firstLoad) { <?php if ($block->getNodeClickListener()): ?> - this.addListener('click', <?php echo $block->escapeJs($block->getNodeClickListener()) ?>.createDelegate(this)); + this.addListener('click', <?php echo $block->escapeHtml($block->getNodeClickListener()) ?>.createDelegate(this)); <?php endif; ?> } @@ -149,25 +149,25 @@ jQuery(function() }; categoryLoader.on("beforeload", function(treeLoader, node) { - $('<?php echo $block->escapeJs($_divId); ?>').fire('category:beforeLoad', {treeLoader:treeLoader}); + $('<?php echo $block->escapeHtml($_divId); ?>').fire('category:beforeLoad', {treeLoader:treeLoader}); treeLoader.baseParams.id = node.attributes.id; }); - tree<?php echo $block->escapeJs($block->getId()) ?> = new Ext.tree.TreePanel.Enhanced('<?php echo $block->escapeJs($_divId) ?>', { + tree<?php echo $block->escapeHtml($block->getId()) ?> = new Ext.tree.TreePanel.Enhanced('<?php echo $block->escapeHtml($_divId) ?>', { animate: false, loader: categoryLoader, enableDD: false, containerScroll: true, - rootVisible: '<?php echo $block->escapeJs($block->getRoot()->getIsVisible()) ?>', + rootVisible: '<?php echo $block->escapeHtml($block->getRoot()->getIsVisible()) ?>', useAjax: true, currentNodeId: <?php echo (int) $block->getCategoryId() ?>, addNodeTo: false }); if (useMassaction) { - tree<?php echo $block->escapeJs($block->getId()) ?>.on('check', function(node) { - $('<?php echo $block->escapeJs($_divId); ?>').fire('node:changed', {node:node}); - }, tree<?php echo $block->escapeJs($block->getId()) ?>); + tree<?php echo $block->escapeHtml($block->getId()) ?>.on('check', function(node) { + $('<?php echo $block->escapeHtml($_divId); ?>').fire('node:changed', {node:node}); + }, tree<?php echo $block->escapeHtml($block->getId()) ?>); } // set the root node @@ -179,7 +179,7 @@ jQuery(function() category_id: <?php echo (int) $block->getCategoryId() ?> }; - tree<?php echo $block->escapeJs($block->getId()) ?>.loadTree({parameters:parameters, data:<?php /* @noEscape */ echo $block->getTreeJson() ?>},true); + tree<?php echo $block->escapeHtml($block->getId()) ?>.loadTree({parameters:parameters, data:<?php /* @noEscape */ echo $block->getTreeJson() ?>},true); }); diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index 612053a6ab0..fac1674c3e5 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -39,26 +39,27 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</div>'+ '<div class="fieldset-wrapper-content">'+ <?php foreach ($block->getDisplayOnContainers() as $container): ?> - '<div class="no-display <?php echo $block->escapeJs($container['code']) ?> group_container" id="<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>]" />'+ - '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][page_id]" value="<%- data.page_id %>" />'+ - '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][layout_handle]" value="<?php echo $block->escapeJs($container['layout_handle']) ?>" />'+ + <?php $containerName = $block->escapeHtmlAttr($container['name']) ?> + '<div class="no-display <?php echo $block->escapeHtmlAttr($container['code']) ?> group_container" id="<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>">'+ + '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>]" />'+ + '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][page_id]" value="<%- data.page_id %>" />'+ + '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][layout_handle]" value="<?php echo $block->escapeHtmlAttr($container['layout_handle']) ?>" />'+ '<table class="data-table">'+ '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeJs(__('%1', $container['label'])) ?></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('%1', $container['label'])) ?></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ '<td>'+ - '<input disabled="disabled" type="radio" class="radio for_all" id="all_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][for]" value="all" onclick="WidgetInstance.togglePageGroupChooser(this)" checked="checked" /> '+ - '<label for="all_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>"><?php echo $block->escapeJs(__('All')) ?></label><br />'+ - '<input disabled="disabled" type="radio" class="radio for_specific" id="specific_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][for]" value="specific" onclick="WidgetInstance.togglePageGroupChooser(this)" /> '+ - '<label for="specific_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>"><?php echo $block->escapeJs(__('Specific %1', $container['label'])) ?></label>'+ + '<input disabled="disabled" type="radio" class="radio for_all" id="all_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][for]" value="all" onclick="WidgetInstance.togglePageGroupChooser(this)" checked="checked" /> '+ + '<label for="all_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>"><?php echo $block->escapeHtml(__('All')) ?></label><br />'+ + '<input disabled="disabled" type="radio" class="radio for_specific" id="specific_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][for]" value="specific" onclick="WidgetInstance.togglePageGroupChooser(this)" /> '+ + '<label for="specific_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>"><?php echo $block->escapeHtml(__('Specific %1', $container['label'])) ?></label>'+ '</td>'+ '<td>'+ '<div class="block_reference_container">'+ @@ -73,16 +74,16 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</tr>'+ '</tbody>'+ '</table>'+ - '<div class="no-display chooser_container" id="<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="is_anchor_only" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][is_anchor_only]" value="<?php echo $block->escapeJs($container['is_anchor_only']) ?>" />'+ - '<input disabled="disabled" type="hidden" class="product_type_id" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][product_type_id]" value="<?php echo $block->escapeJs($container['product_type_id']) ?>" />'+ + '<div class="no-display chooser_container" id="<?php /* @noEscape */ echo $containerName ?>_ids_<%- data.id %>">'+ + '<input disabled="disabled" type="hidden" class="is_anchor_only" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][is_anchor_only]" value="<?php echo $block->escapeHtmlAttr($container['is_anchor_only']) ?>" />'+ + '<input disabled="disabled" type="hidden" class="product_type_id" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][product_type_id]" value="<?php echo $block->escapeHtmlAttr($container['product_type_id']) ?>" />'+ '<p>' + - '<input disabled="disabled" type="text" class="input-text entities" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][entities]" value="<%- data.<?php echo $block->escapeJs($container['name']) ?>_entities %>" readonly="readonly" /> ' + - '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php echo $block->escapeJs($container['code']) ?>\', \'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Open Chooser')) ?>">' + - '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_chooser_trigger.gif')) ?>" alt="<?php echo $block->escapeJs(__('Open Chooser')); ?>" />' + + '<input disabled="disabled" type="text" class="input-text entities" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][entities]" value="<%- data.<?php /* @noEscape */ echo $containerName ?>_entities %>" readonly="readonly" /> ' + + '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php echo $block->escapeHtml($container['code']) ?>\', \'<?php /* @noEscape */ echo $containerName ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeHtmlAttr(__('Open Chooser')) ?>">' + + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_chooser_trigger.gif')) ?>" alt="<?php echo $block->escapeHtmlAttr(__('Open Chooser')); ?>" />' + '</a> ' + - '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Apply')); ?>">' + - '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>" alt="<?php echo $block->escapeJs(__('Apply')); ?>" />' + + '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeHtml($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeHtmlAttr(__('Apply')); ?>">' + + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>" alt="<?php echo $block->escapeHtmlAttr(__('Apply')); ?>" />' + '</a>' + '</p>'+ '<div class="chooser"></div>'+ @@ -98,8 +99,8 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ '<th> </th>'+ '</tr>'+ '</thead>'+ @@ -128,14 +129,14 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Page')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php echo $block->escapeJs($block->getLayoutsChooser()) ?></td>'+ + '<td><?php /* @noEscape */ echo $block->getLayoutsChooser() ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ @@ -159,14 +160,14 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Page')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php echo $block->escapeJs($block->getPageLayoutsPageChooser()) ?></td>'+ + '<td><?php /* @noEscape */ echo $block->getPageLayoutsPageChooser() ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ -- GitLab From 8d27ecac1a9a6aa4b55e390a4ddbd89d5d4612e5 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Wed, 10 Aug 2016 18:24:30 +0300 Subject: [PATCH 255/838] MAGETWO-56572: Introduce and implement ShipmentCommentCreationInterface --- .../Magento/Sales/Api/Data/EntityInterface.php | 3 ++- .../Sales/Api/Data/InvoiceCommentInterface.php | 6 ++++-- .../Sales/Api/Data/InvoiceItemInterface.php | 18 +++++++++++++++++- .../Data/ShipmentCommentCreationInterface.php | 4 +++- .../Api/Data/ShipmentCommentInterface.php | 6 ++++-- .../Model/Order/Shipment/CommentCreation.php | 3 +-- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/EntityInterface.php b/app/code/Magento/Sales/Api/Data/EntityInterface.php index 30eb054bc2c..d09b25920f8 100644 --- a/app/code/Magento/Sales/Api/Data/EntityInterface.php +++ b/app/code/Magento/Sales/Api/Data/EntityInterface.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Api\Data; /** * Interface EntityInterface + * @api */ interface EntityInterface { @@ -49,4 +50,4 @@ interface EntityInterface * @return $this */ public function setEntityId($entityId); -} \ No newline at end of file +} diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php index b81a7b3b07b..dd9b1a77180 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php @@ -12,8 +12,10 @@ namespace Magento\Sales\Api\Data; * invoice history. * @api */ -interface InvoiceCommentInterface extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\CommentInterface, \Magento\Sales\Api\Data\EntityInterface +interface InvoiceCommentInterface + extends \Magento\Framework\Api\ExtensibleDataInterface, + \Magento\Sales\Api\Data\CommentInterface, + \Magento\Sales\Api\Data\EntityInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php index 7ea3646c0bb..0f07bfcad23 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php @@ -11,7 +11,8 @@ namespace Magento\Sales\Api\Data; * An invoice is a record of the receipt of payment for an order. An invoice item is a purchased item in an invoice. * @api */ -interface InvoiceItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface, +interface InvoiceItemInterface + extends \Magento\Framework\Api\ExtensibleDataInterface, \Magento\Sales\Api\Data\LineItemInterface { /**#@+ @@ -448,4 +449,19 @@ interface InvoiceItemInterface extends \Magento\Framework\Api\ExtensibleDataInte * @return $this */ public function setBaseDiscountTaxCompensationAmount($amount); + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\InvoiceItemExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes(\Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes); } diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php index 62495a654ae..0c17af1aae2 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php @@ -7,8 +7,10 @@ namespace Magento\Sales\Api\Data; /** * Interface ShipmentCommentCreationInterface + * @api */ -interface ShipmentCommentCreationInterface extends \Magento\Framework\Api\ExtensibleDataInterface, +interface ShipmentCommentCreationInterface + extends \Magento\Framework\Api\ExtensibleDataInterface, \Magento\Sales\Api\Data\CommentInterface { /** diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php index 8c01cecd98d..3b17b1b9559 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php @@ -12,8 +12,10 @@ namespace Magento\Sales\Api\Data; * document lists the products and their quantities in the delivery package. A shipment document can contain comments. * @api */ -interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\CommentInterface, \Magento\Sales\Api\Data\EntityInterface +interface ShipmentCommentInterface + extends \Magento\Framework\Api\ExtensibleDataInterface, + \Magento\Sales\Api\Data\CommentInterface, + \Magento\Sales\Api\Data\EntityInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. diff --git a/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php index b32aa7bb297..89c92ad80f7 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php @@ -45,8 +45,7 @@ class CommentCreation implements ShipmentCommentCreationInterface */ public function setExtensionAttributes( \Magento\Sales\Api\Data\ShipmentCommentCreationExtensionInterface $extensionAttributes - ) - { + ) { $this->extensionAttributes = $extensionAttributes; return $this; } -- GitLab From 53f2780068599dce74c6190f886961f3e2d1b8bb Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Wed, 10 Aug 2016 18:43:09 +0300 Subject: [PATCH 256/838] MAGETWO-55193: Extension Management with Marketplace data - CR fixes --- .../src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php index fd02a3b402f..2603338c342 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php @@ -98,7 +98,7 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase [ 'magento/package-2', '1.0.1', - ['x-magento-ext-title'=> 'Package2 title', 'x-magento-ext-package-link' => 'http://test.de'] + ['x-magento-ext-title'=> 'Package2 title', 'x-magento-ext-package-link' => 'http://example.com'] ], ] ); @@ -122,7 +122,7 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase 'update' => false, 'uninstall' => true, 'vendor' => 'Magento', - 'link' => 'http://test.de', + 'link' => 'http://example.com', ], ]; -- GitLab From 35e158cb4a9581c37f6762eff0ebe477f7371ea5 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 09:26:46 -0500 Subject: [PATCH 257/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module Applying escape functions in templates --- .../templates/system/config/validatevat.phtml | 4 ++-- .../view/adminhtml/templates/tab/cart.phtml | 18 +++++++++--------- .../view/frontend/templates/address/edit.phtml | 2 +- .../frontend/templates/form/register.phtml | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index be1e66d94b7..8b5a486a26b 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -16,8 +16,8 @@ require(['prototype'], function(){ var validationMessage = $('validation_result'); params = { - country: $('<?php echo $block->escapeJs($block->getMerchantCountryField()); ?>').value, - vat: $('<?php echo $block->escapeJs($block->getMerchantVatNumberField()); ?>').value + country: $('<?php echo $block->escapeHtml($block->getMerchantCountryField()); ?>').value, + vat: $('<?php echo $block->escapeHtml($block->getMerchantVatNumberField()); ?>').value }; new Ajax.Request('<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>', { diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index f8ca555c2ad..9845da2ac40 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -29,19 +29,19 @@ require([ "Magento_Catalog/catalog/product/composite/configure" ], function(alert, confirm){ -<?php echo $block->escapeJs($block->getJsObjectName()) ?>cartControl = { +<?php echo $block->escapeHtml($block->getJsObjectName()) ?>cartControl = { reload: function (params) { if (!params) { params = {}; } - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = params; - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reload(); - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = {}; + <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.reloadParams = params; + <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.reload(); + <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.reloadParams = {}; }, configureItem: function (itemId) { - productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($listType) ?>', this.cbOnLoadIframe.bind(this)); - productConfigure.showItemConfiguration('<?php echo $block->escapeJs($listType) ?>', itemId); + productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeHtml($listType) ?>', this.cbOnLoadIframe.bind(this)); + productConfigure.showItemConfiguration('<?php echo $block->escapeHtml($listType) ?>', itemId); return false; }, @@ -57,14 +57,14 @@ require([ if (!itemId) { alert({ - content: '<?php echo $block->escapeJs(__('No item specified.')) ?>' + content: '<?php echo $block->escapeHtml(__('No item specified.')) ?>' }); return false; } confirm({ - content: '<?php echo $block->escapeJs(__('Are you sure you want to remove this item?')) ?>', + content: '<?php echo $block->escapeHtml(__('Are you sure you want to remove this item?')) ?>', actions: { confirm: function(){ self.reload({'delete':itemId}); @@ -81,7 +81,7 @@ $params = [ ]; ?> productConfigure.addListType( - '<?php echo $block->escapeJs($listType) ?>', + '<?php echo $block->escapeHtml($listType) ?>', { urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/configure', $params)) ?>', urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/update', $params)) ?>' diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index f4075b8516d..3af2ad2f5bb 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -213,7 +213,7 @@ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->getRegionId()) ?>", + "defaultRegion": "<?php echo $block->escapeHtml($block->getRegionId()) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index b35727b26fb..a2943c02ae6 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -210,7 +210,7 @@ require([ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->getFormData()->getRegionId()) ?>", + "defaultRegion": "<?php echo $block->escapeHtml($block->getFormData()->getRegionId()) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } -- GitLab From fa547432becf07cc939cc5a2edb67b59521f13fa Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 09:28:19 -0500 Subject: [PATCH 258/838] MAGETWO-55921: Eliminate @escapeNotVerified in Newsletter Module Applying escape functions in templates --- .../Newsletter/view/adminhtml/templates/template/edit.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index 61bfd057d45..9f32fc9a8e4 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -176,9 +176,9 @@ require([ preview: function() { if (this.typeChange) { - $('preview_type').value = <?php echo $block->escapeJs(TemplateTypesInterface::TYPE_TEXT) ?>; + $('preview_type').value = <?php echo $block->escapeHtml(TemplateTypesInterface::TYPE_TEXT) ?>; } else { - $('preview_type').value = <?php echo $block->escapeJs($block->getTemplateType()) ?>; + $('preview_type').value = <?php echo $block->escapeHtml($block->getTemplateType()) ?>; } if (this.isEditor() && tinyMCE.get(this.id)) { tinyMCE.triggerSave(); @@ -219,7 +219,7 @@ require([ }; templateControl.init(); - templateControl.templateName = "<?php echo $block->escapeJs($block->getJsTemplateName()) ?>"; + templateControl.templateName = "<?php echo $block->escapeHtml($block->getJsTemplateName()) ?>"; //]]> }); -- GitLab From 8acda82e7a3cf5a8ee4142dc7c5126783269949c Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 09:30:12 -0500 Subject: [PATCH 259/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module Applying escape functions in templates --- .../adminhtml/templates/customer/edit/tab/wishlist.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index 63377fcbbbe..bc580057279 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -21,13 +21,13 @@ if (!urlParams) { urlParams = ''; } - var url = <?php echo $block->escapeJs($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; + var url = <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; new Ajax.Updater( - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.containerId, + <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.containerId, url, { parameters: {form_key: FORM_KEY}, - onComplete: <?php echo $block->escapeJs($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeJs($block->getJsObjectName()) ?>), + onComplete: <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeHtml($block->getJsObjectName()) ?>), evalScripts:true } ); -- GitLab From 1847b4c9e1056e1683b14b2729a60979d81281a7 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 11:58:21 -0500 Subject: [PATCH 260/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module Applying escape functions in templates --- .../Captcha/view/adminhtml/templates/default.phtml | 2 +- .../view/frontend/templates/customer/list.phtml | 2 +- lib/internal/Magento/Framework/Escaper.php | 12 ++++++++++-- .../Magento/Framework/Test/Unit/EscaperTest.php | 11 +++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index 1aceb9ff95d..905d9149140 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -44,7 +44,7 @@ require(["prototype", "mage/captcha"], function(){ //<![CDATA[ - var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeJs($block->getFormId()) ?>'); + var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeHtml($block->getFormId()) ?>'); $('captcha-reload').observe('click', function () { captcha.refresh(this); diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index 9eb6259230d..578f8d19c22 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -27,7 +27,7 @@ <td data-th="<?php echo $block->escapeHtml(__('Created')) ?>" class="col date"><?php echo $block->escapeHtml($block->dateFormat($_review->getReviewCreatedAt())); ?></td> <td data-th="<?php echo $block->escapeHtml(__('Product Name')) ?>" class="col item"> <strong class="product-name"> - <a href="<?php echo $block->escapeUrl($block->getProductUrl()) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a> + <a href="<?php echo $block->escapeUrl($block->getProductUrl($_review)) ?>"><?php echo $block->escapeHtml($_review->getName()) ?></a> </strong> </td> <td data-th="<?php echo $block->escapeHtml(__('Rating')) ?>" class="col summary"> diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fe88e2b0792..95feeb86f41 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -32,9 +32,17 @@ class Escaper } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { $allowed = implode('|', $allowedTags); - $result = preg_replace('/<([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)>/si', '##$1$2$3##', $data); + $result = preg_replace( + '/<([\/\s\r\n]*)(' . $allowed . '[^>]*)([\/\s\r\n]*)>/si', + '##$1$2$3##', + $data + ); $result = htmlspecialchars($result, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); - $result = preg_replace('/##([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)##/si', '<$1$2$3>', $result); + $result = preg_replace( + '/##([\/\s\r\n]*)(' . $allowed . '[^##]*)([\/\s\r\n]*)##/si', + '<$1$2$3>', + $result + ); } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 7348537c326..b4f1c8f63ee 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -62,7 +62,18 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'data' => '<span><b>some text in tags</b></span>', 'expected' => '<span><b>some text in tags</b></span>', 'allowedTags' => ['span', 'b'], + ], + 'string data with allowed tags 2' => [ + 'data' => '<span><b class="price">some text in tags</b></span>', + 'expected' => '<span><b class="price">some text in tags</b></span>', + 'allowedTags' => ['span', 'b'], + ], + 'string data with allowed tags 3' => [ + 'data' => '<span><b class="price"/></span>', + 'expected' => '<span><b class="price"/></span>', + 'allowedTags' => ['span', 'b'], ] + ]; } -- GitLab From 5289d3ef779bf187baad851c9f54308009ca783f Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 13:32:13 -0500 Subject: [PATCH 261/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module Applying escape functions in templates --- .../Customer/view/adminhtml/templates/tab/cart.phtml | 4 ++-- lib/internal/Magento/Framework/Escaper.php | 12 ++---------- .../Magento/Framework/Test/Unit/EscaperTest.php | 11 ----------- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index 9845da2ac40..95a18f22191 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -57,14 +57,14 @@ require([ if (!itemId) { alert({ - content: '<?php echo $block->escapeHtml(__('No item specified.')) ?>' + content: '<?php echo $block->escapeJs(__('No item specified.')) ?>' }); return false; } confirm({ - content: '<?php echo $block->escapeHtml(__('Are you sure you want to remove this item?')) ?>', + content: '<?php echo $block->escapeJs(__('Are you sure you want to remove this item?')) ?>', actions: { confirm: function(){ self.reload({'delete':itemId}); diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 95feeb86f41..fe88e2b0792 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -32,17 +32,9 @@ class Escaper } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { $allowed = implode('|', $allowedTags); - $result = preg_replace( - '/<([\/\s\r\n]*)(' . $allowed . '[^>]*)([\/\s\r\n]*)>/si', - '##$1$2$3##', - $data - ); + $result = preg_replace('/<([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)>/si', '##$1$2$3##', $data); $result = htmlspecialchars($result, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); - $result = preg_replace( - '/##([\/\s\r\n]*)(' . $allowed . '[^##]*)([\/\s\r\n]*)##/si', - '<$1$2$3>', - $result - ); + $result = preg_replace('/##([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)##/si', '<$1$2$3>', $result); } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index b4f1c8f63ee..7348537c326 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -62,18 +62,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'data' => '<span><b>some text in tags</b></span>', 'expected' => '<span><b>some text in tags</b></span>', 'allowedTags' => ['span', 'b'], - ], - 'string data with allowed tags 2' => [ - 'data' => '<span><b class="price">some text in tags</b></span>', - 'expected' => '<span><b class="price">some text in tags</b></span>', - 'allowedTags' => ['span', 'b'], - ], - 'string data with allowed tags 3' => [ - 'data' => '<span><b class="price"/></span>', - 'expected' => '<span><b class="price"/></span>', - 'allowedTags' => ['span', 'b'], ] - ]; } -- GitLab From 453a773c4660a3a64e99dfd29bf3de3df6210ca2 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 10 Aug 2016 14:37:17 -0500 Subject: [PATCH 262/838] MAGETWO-56673: XssOutputValidatorTest fails on safe output Applying escape functions in templates --- .../Magento/TestFramework/Utility/XssOutputValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php index 43f4c6eaa6b..1e0d684c124 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php +++ b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php @@ -34,7 +34,7 @@ class XssOutputValidator * * @var string[] */ - private $escapeFunctions = ['escapeHtmlAttr', 'escapeUrl', 'escapeJs', 'escapeCss']; + private $escapeFunctions = ['escapeHtml', 'escapeHtmlAttr', 'escapeUrl', 'escapeJs', 'escapeCss']; /** * -- GitLab From 0699d5ee08a643ef58852d16324d9000d741ecf4 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sat, 12 Mar 2016 10:12:39 +0100 Subject: [PATCH 263/838] Add HttpInterface methods and add up-casts for type safety --- .../Framework/App/Response/HttpInterface.php | 45 +++++++++++++++++++ .../Framework/Controller/AbstractResult.php | 9 ++-- .../Framework/Controller/Result/Json.php | 13 +++++- .../Framework/Controller/Result/Raw.php | 15 ++++++- .../Framework/Controller/Result/Redirect.php | 18 ++++++-- .../Controller/Test/Unit/Result/RawTest.php | 11 +++-- .../Test/Unit/Result/RedirectTest.php | 7 +-- .../Magento/Framework/View/Result/Layout.php | 29 +++++++++--- .../Magento/Framework/View/Result/Page.php | 16 +++++-- 9 files changed, 136 insertions(+), 27 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Response/HttpInterface.php b/lib/internal/Magento/Framework/App/Response/HttpInterface.php index cf51d7689a8..1748dec2230 100644 --- a/lib/internal/Magento/Framework/App/Response/HttpInterface.php +++ b/lib/internal/Magento/Framework/App/Response/HttpInterface.php @@ -16,4 +16,49 @@ interface HttpInterface extends \Magento\Framework\App\ResponseInterface * @return void */ public function setHttpResponseCode($code); + + /** + * Set a header + * + * If $replace is true, replaces any headers already defined with that + * $name. + * + * @param string $name + * @param string $value + * @param boolean $replace + * @return self + */ + public function setHeader($name, $value, $replace = false); + + /** + * @param int|string $httpCode + * @param null|int|string $version + * @param null|string $phrase + * @return self + */ + public function setStatusHeader($httpCode, $version = null, $phrase = null); + + /** + * @param string $value + * @return self + */ + public function appendBody($value); + + /** + * @param string $value + * @return self + */ + public function setBody($value); + + /** + * Set redirect URL + * + * Sets Location header and response code. Forces replacement of any prior + * redirects. + * + * @param string $url + * @param int $code + * @return self + */ + public function setRedirect($url, $code = 302); } diff --git a/lib/internal/Magento/Framework/Controller/AbstractResult.php b/lib/internal/Magento/Framework/Controller/AbstractResult.php index 2c62b149619..ee02248ff0b 100644 --- a/lib/internal/Magento/Framework/Controller/AbstractResult.php +++ b/lib/internal/Magento/Framework/Controller/AbstractResult.php @@ -7,6 +7,7 @@ namespace Magento\Framework\Controller; use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; abstract class AbstractResult implements ResultInterface { @@ -83,10 +84,10 @@ abstract class AbstractResult implements ResultInterface } /** - * @param ResponseInterface $response + * @param HttpResponseInterface $response * @return $this */ - protected function applyHttpHeaders(ResponseInterface $response) + protected function applyHttpHeaders(HttpResponseInterface $response) { if (!empty($this->httpResponseCode)) { $response->setHttpResponseCode($this->httpResponseCode); @@ -105,7 +106,7 @@ abstract class AbstractResult implements ResultInterface } return $this; } - + /** * @param ResponseInterface $response * @return $this @@ -115,7 +116,7 @@ abstract class AbstractResult implements ResultInterface /** * Render content * - * @param ResponseInterface $response + * @param HttpResponseInterface|ResponseInterface $response * @return $this */ public function renderResult(ResponseInterface $response) diff --git a/lib/internal/Magento/Framework/Controller/Result/Json.php b/lib/internal/Magento/Framework/Controller/Result/Json.php index aae0257048a..e80e02ea7f8 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Json.php +++ b/lib/internal/Magento/Framework/Controller/Result/Json.php @@ -6,6 +6,7 @@ namespace Magento\Framework\Controller\Result; +use Magento\Framework\App\Response\Http as HttpResponse; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\AbstractResult; use Magento\Framework\Translate\InlineInterface; @@ -59,9 +60,19 @@ class Json extends AbstractResult } /** - * {@inheritdoc} + * @param HttpResponse|ResponseInterface $response + * @return $this */ protected function render(ResponseInterface $response) + { + return $this->renderHttpResponse($response); + } + + /** + * @param HttpResponse $response + * @return $this + */ + private function renderHttpResponse(HttpResponse $response) { $this->translateInline->processResponseBody($this->json, true); $response->representJson($this->json); diff --git a/lib/internal/Magento/Framework/Controller/Result/Raw.php b/lib/internal/Magento/Framework/Controller/Result/Raw.php index 4cfbc1e02d4..0295b513f24 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Raw.php +++ b/lib/internal/Magento/Framework/Controller/Result/Raw.php @@ -6,6 +6,7 @@ namespace Magento\Framework\Controller\Result; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\AbstractResult; @@ -31,11 +32,21 @@ class Raw extends AbstractResult } /** - * {@inheritdoc} + * @param HttpResponseInterface|ResponseInterface $response + * @return $this */ protected function render(ResponseInterface $response) { - $response->setBody($this->contents); + return $this->renderHttpResponse($response); + } + + /** + * @param HttpResponseInterface $httpResponse + * @return $this + */ + private function renderHttpResponse(HttpResponseInterface $httpResponse) + { + $httpResponse->setBody($this->contents); return $this; } } diff --git a/lib/internal/Magento/Framework/Controller/Result/Redirect.php b/lib/internal/Magento/Framework/Controller/Result/Redirect.php index 391beb84cd8..7ac3415294a 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Redirect.php +++ b/lib/internal/Magento/Framework/Controller/Result/Redirect.php @@ -7,6 +7,8 @@ namespace Magento\Framework\Controller\Result; use Magento\Framework\App; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; +use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\AbstractResult; /** @@ -90,11 +92,21 @@ class Redirect extends AbstractResult } /** - * {@inheritdoc} + * @param HttpResponseInterface|ResponseInterface $response + * @return $this + */ + protected function render(ResponseInterface $response) + { + return $this->renderHttpResponse($response); + } + + /** + * @param HttpResponseInterface $httpResponse + * @return $this */ - protected function render(App\ResponseInterface $response) + private function renderHttpResponse(HttpResponseInterface $httpResponse) { - $response->setRedirect($this->url); + $httpResponse->setRedirect($this->url); return $this; } } diff --git a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RawTest.php b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RawTest.php index 402838fb091..21e172b0dd4 100644 --- a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RawTest.php +++ b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RawTest.php @@ -6,6 +6,7 @@ namespace Magento\Framework\Controller\Test\Unit\Result; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; class RawTest extends \PHPUnit_Framework_TestCase @@ -13,7 +14,7 @@ class RawTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Framework\Controller\Result\Raw */ protected $raw; - /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject*/ + /** @var HttpResponseInterface|\PHPUnit_Framework_MockObject_MockObject*/ protected $response; /** @var ObjectManagerHelper */ @@ -24,15 +25,13 @@ class RawTest extends \PHPUnit_Framework_TestCase $this->objectManagerHelper = new ObjectManagerHelper($this); $this->response = $this->getMock( - \Magento\Framework\App\ResponseInterface::class, - ['setBody', 'sendResponse'], + HttpResponseInterface::class, + [], [], '', false ); - $this->raw = $this->objectManagerHelper->getObject( - \Magento\Framework\Controller\Result\Raw::class - ); + $this->raw = $this->objectManagerHelper->getObject(\Magento\Framework\Controller\Result\Raw::class); } public function testSetContents() diff --git a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php index ce703f02bd7..9b957818fff 100644 --- a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php +++ b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/RedirectTest.php @@ -6,6 +6,7 @@ namespace Magento\Framework\Controller\Test\Unit\Result; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use \Magento\Framework\Controller\Result\Redirect; class RedirectTest extends \PHPUnit_Framework_TestCase @@ -22,7 +23,7 @@ class RedirectTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $urlInterface; - /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var HttpResponseInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $response; protected function setUp() @@ -49,8 +50,8 @@ class RedirectTest extends \PHPUnit_Framework_TestCase false ); $this->response = $this->getMock( - \Magento\Framework\App\ResponseInterface::class, - ['setRedirect', 'sendResponse'], + HttpResponseInterface::class, + [], [], '', false diff --git a/lib/internal/Magento/Framework/View/Result/Layout.php b/lib/internal/Magento/Framework/View/Result/Layout.php index 4094f1dc60c..fd4061551ac 100644 --- a/lib/internal/Magento/Framework/View/Result/Layout.php +++ b/lib/internal/Magento/Framework/View/Result/Layout.php @@ -7,6 +7,7 @@ namespace Magento\Framework\View\Result; use Magento\Framework; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\AbstractResult; use Magento\Framework\View; @@ -152,10 +153,19 @@ class Layout extends AbstractResult /** * Render current layout * - * @param ResponseInterface $response + * @param HttpResponseInterface|ResponseInterface $response * @return $this */ public function renderResult(ResponseInterface $response) + { + return $this->renderHttpResult($response); + } + + /** + * @param HttpResponseInterface $httpResponse + * @return $this + */ + private function renderHttpResult(HttpResponseInterface $httpResponse) { \Magento\Framework\Profiler::start('LAYOUT'); \Magento\Framework\Profiler::start('layout_render'); @@ -163,8 +173,8 @@ class Layout extends AbstractResult $this->eventManager->dispatch('layout_render_before'); $this->eventManager->dispatch('layout_render_before_' . $this->request->getFullActionName()); - $this->applyHttpHeaders($response); - $this->render($response); + $this->applyHttpHeaders($httpResponse); + $this->render($httpResponse); \Magento\Framework\Profiler::stop('layout_render'); \Magento\Framework\Profiler::stop('LAYOUT'); @@ -174,14 +184,23 @@ class Layout extends AbstractResult /** * Render current layout * - * @param ResponseInterface $response + * @param HttpResponseInterface|ResponseInterface $response * @return $this */ protected function render(ResponseInterface $response) + { + return $this->renderHttpResponse($response); + } + + /** + * @param HttpResponseInterface $httpResponse + * @return $this + */ + private function renderHttpResponse(HttpResponseInterface $httpResponse) { $output = $this->layout->getOutput(); $this->translateInline->processResponseBody($output); - $response->appendBody($output); + $httpResponse->appendBody($output); return $this; } } diff --git a/lib/internal/Magento/Framework/View/Result/Page.php b/lib/internal/Magento/Framework/View/Result/Page.php index 952dcabddc1..6bec99cfe30 100644 --- a/lib/internal/Magento/Framework/View/Result/Page.php +++ b/lib/internal/Magento/Framework/View/Result/Page.php @@ -7,6 +7,7 @@ namespace Magento\Framework\View\Result; use Magento\Framework; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\View; @@ -219,10 +220,19 @@ class Page extends Layout } /** - * @param ResponseInterface $response + * @param HttpResponseInterface|ResponseInterface $response * @return $this */ protected function render(ResponseInterface $response) + { + return $this->renderHttpResponse($response); + } + + /** + * @param HttpResponseInterface $httpResponse + * @return $this + */ + private function renderHttpResponse(HttpResponseInterface $httpResponse) { $this->pageConfig->publicBuild(); if ($this->getPageLayout()) { @@ -244,9 +254,9 @@ class Page extends Layout $this->assign('layoutContent', $output); $output = $this->renderPage(); $this->translateInline->processResponseBody($output); - $response->appendBody($output); + $httpResponse->appendBody($output); } else { - parent::render($response); + parent::render($httpResponse); } return $this; } -- GitLab From 6f5592f72f9198cd24c53f1d8ad99a1d0043f5af Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sun, 8 May 2016 09:47:14 +0200 Subject: [PATCH 264/838] Make PHPDoc comments adhere to standard and getHeader and clearHeader and getHttpResponseCode to interface --- .../Framework/App/Response/HttpInterface.php | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Response/HttpInterface.php b/lib/internal/Magento/Framework/App/Response/HttpInterface.php index 1748dec2230..a0b04b34a47 100644 --- a/lib/internal/Magento/Framework/App/Response/HttpInterface.php +++ b/lib/internal/Magento/Framework/App/Response/HttpInterface.php @@ -17,11 +17,17 @@ interface HttpInterface extends \Magento\Framework\App\ResponseInterface */ public function setHttpResponseCode($code); + /** + * Get HTTP response code + * + * @return int + */ + public function getHttpResponseCode(); + /** * Set a header * - * If $replace is true, replaces any headers already defined with that - * $name. + * If $replace is true, replaces any headers already defined with that $name. * * @param string $name * @param string $value @@ -31,6 +37,34 @@ interface HttpInterface extends \Magento\Framework\App\ResponseInterface public function setHeader($name, $value, $replace = false); /** + * Get header value by name + * + * Returns first found header by passed name. + * If header with specified name was not found returns false. + * + * @param string $name + * @return \Zend\Http\Header\HeaderInterface|bool + */ + public function getHeader($name); + + /** + * Remove header by name from header stack + * + * @param string $name + * @return self + */ + public function clearHeader($name); + + /** + * Allow granular setting of HTTP response status code, version and phrase + * + * For example, a HTTP response as the following: + * HTTP 200 1.1 Your response has been served + * Can be set with the arguments + * $httpCode = 200 + * $version = 1.1 + * $phrase = 'Your response has been served' + * * @param int|string $httpCode * @param null|int|string $version * @param null|string $phrase @@ -39,12 +73,18 @@ interface HttpInterface extends \Magento\Framework\App\ResponseInterface public function setStatusHeader($httpCode, $version = null, $phrase = null); /** + * Append the given string to the response body + * * @param string $value * @return self */ public function appendBody($value); /** + * Set the response body to the given value + * + * Any previously set contents will be replaced by the new content. + * * @param string $value * @return self */ @@ -53,8 +93,7 @@ interface HttpInterface extends \Magento\Framework\App\ResponseInterface /** * Set redirect URL * - * Sets Location header and response code. Forces replacement of any prior - * redirects. + * Sets Location header and response code. Forces replacement of any prior redirects. * * @param string $url * @param int $code -- GitLab From 2084f2e74954881d49c73655281918ddf286df93 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sun, 8 May 2016 09:47:52 +0200 Subject: [PATCH 265/838] Replace all PHPDoc comments for interface method implementations with {@inheritdoc} --- .../HTTP/PhpEnvironment/Response.php | 52 ++++--------------- 1 file changed, 10 insertions(+), 42 deletions(-) diff --git a/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php b/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php index 8c8a90ae653..f077635122a 100644 --- a/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php +++ b/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php @@ -16,12 +16,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr protected $isRedirect = false; /** - * Get header value by name. - * Returns first found header by passed name. - * If header with specified name was not found returns false. - * - * @param string $name - * @return \Zend\Http\Header\HeaderInterface|bool + * {@inheritdoc} */ public function getHeader($name) { @@ -45,8 +40,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * @param string $value - * @return $this + * {@inheritdoc} */ public function appendBody($value) { @@ -56,8 +50,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * @param string $value - * @return $this + * {@inheritdoc} */ public function setBody($value) { @@ -76,15 +69,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * Set a header - * - * If $replace is true, replaces any headers already defined with that - * $name. - * - * @param string $name - * @param string $value - * @param boolean $replace - * @return $this + * {@inheritdoc} */ public function setHeader($name, $value, $replace = false) { @@ -99,10 +84,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * Remove header by name from header stack - * - * @param string $name - * @return $this + * {@inheritdoc} */ public function clearHeader($name) { @@ -117,6 +99,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr /** * Remove all headers + * * @return $this */ public function clearHeaders() @@ -128,14 +111,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * Set redirect URL - * - * Sets Location header and response code. Forces replacement of any prior - * redirects. - * - * @param string $url - * @param int $code - * @return $this + * {@inheritdoc} */ public function setRedirect($url, $code = 302) { @@ -146,10 +122,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * Set HTTP response code to use with headers - * - * @param int $code - * @return $this + * {@inheritdoc} */ public function setHttpResponseCode($code) { @@ -164,10 +137,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * @param int|string $httpCode - * @param null|int|string $version - * @param null|string $phrase - * @return $this + * {@inheritdoc} */ public function setStatusHeader($httpCode, $version = null, $phrase = null) { @@ -182,9 +152,7 @@ class Response extends \Zend\Http\PhpEnvironment\Response implements \Magento\Fr } /** - * Get response code - * - * @return int + * {@inheritdoc} */ public function getHttpResponseCode() { -- GitLab From c930932843bc3aa164c55dca59f23096348c2fed Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Thu, 12 May 2016 08:54:18 +0200 Subject: [PATCH 266/838] Change signature of render() method to receive HttpResponseInterface --- .../Backend/Model/View/Result/Redirect.php | 3 +- .../Framework/Controller/AbstractResult.php | 4 +-- .../Framework/Controller/Result/Forward.php | 4 +-- .../Framework/Controller/Result/Json.php | 20 +++-------- .../Framework/Controller/Result/Raw.php | 17 ++-------- .../Framework/Controller/Result/Redirect.php | 17 ++-------- .../Controller/Test/Unit/Result/JsonTest.php | 7 ++-- .../Magento/Framework/View/Result/Layout.php | 33 ++++--------------- .../Magento/Framework/View/Result/Page.php | 19 +++-------- 9 files changed, 31 insertions(+), 93 deletions(-) diff --git a/app/code/Magento/Backend/Model/View/Result/Redirect.php b/app/code/Magento/Backend/Model/View/Result/Redirect.php index 799a9f6c55b..239d18acfd5 100644 --- a/app/code/Magento/Backend/Model/View/Result/Redirect.php +++ b/app/code/Magento/Backend/Model/View/Result/Redirect.php @@ -10,6 +10,7 @@ use Magento\Backend\Model\Session; use Magento\Backend\Model\UrlInterface; use Magento\Framework\App; use Magento\Framework\App\ActionFlag; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; class Redirect extends \Magento\Framework\Controller\Result\Redirect { @@ -56,7 +57,7 @@ class Redirect extends \Magento\Framework\Controller\Result\Redirect /** * {@inheritdoc} */ - protected function render(App\ResponseInterface $response) + protected function render(HttpResponseInterface $response) { $this->session->setIsUrlNotice($this->actionFlag->get('', AbstractAction::FLAG_IS_URLS_CHECKED)); return parent::render($response); diff --git a/lib/internal/Magento/Framework/Controller/AbstractResult.php b/lib/internal/Magento/Framework/Controller/AbstractResult.php index ee02248ff0b..afcd4c776dc 100644 --- a/lib/internal/Magento/Framework/Controller/AbstractResult.php +++ b/lib/internal/Magento/Framework/Controller/AbstractResult.php @@ -108,10 +108,10 @@ abstract class AbstractResult implements ResultInterface } /** - * @param ResponseInterface $response + * @param HttpResponseInterface $response * @return $this */ - abstract protected function render(ResponseInterface $response); + abstract protected function render(HttpResponseInterface $response); /** * Render content diff --git a/lib/internal/Magento/Framework/Controller/Result/Forward.php b/lib/internal/Magento/Framework/Controller/Result/Forward.php index 14b94f0b7fb..e1d041d7328 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Forward.php +++ b/lib/internal/Magento/Framework/Controller/Result/Forward.php @@ -7,7 +7,7 @@ namespace Magento\Framework\Controller\Result; use Magento\Framework\App\RequestInterface; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\Controller\AbstractResult; class Forward extends AbstractResult @@ -99,7 +99,7 @@ class Forward extends AbstractResult /** * {@inheritdoc} */ - protected function render(ResponseInterface $response) + protected function render(HttpResponseInterface $response) { return $this; } diff --git a/lib/internal/Magento/Framework/Controller/Result/Json.php b/lib/internal/Magento/Framework/Controller/Result/Json.php index e80e02ea7f8..1b53deb80ca 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Json.php +++ b/lib/internal/Magento/Framework/Controller/Result/Json.php @@ -6,8 +6,7 @@ namespace Magento\Framework\Controller\Result; -use Magento\Framework\App\Response\Http as HttpResponse; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; use Magento\Framework\Controller\AbstractResult; use Magento\Framework\Translate\InlineInterface; @@ -60,22 +59,13 @@ class Json extends AbstractResult } /** - * @param HttpResponse|ResponseInterface $response - * @return $this - */ - protected function render(ResponseInterface $response) - { - return $this->renderHttpResponse($response); - } - - /** - * @param HttpResponse $response - * @return $this + * {@inheritdoc} */ - private function renderHttpResponse(HttpResponse $response) + protected function render(HttpResponseInterface $response) { $this->translateInline->processResponseBody($this->json, true); - $response->representJson($this->json); + $response->setHeader('Content-Type', 'application/json', true); + $response->setBody($this->json); return $this; } } diff --git a/lib/internal/Magento/Framework/Controller/Result/Raw.php b/lib/internal/Magento/Framework/Controller/Result/Raw.php index 0295b513f24..cee562b8039 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Raw.php +++ b/lib/internal/Magento/Framework/Controller/Result/Raw.php @@ -7,7 +7,6 @@ namespace Magento\Framework\Controller\Result; use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; -use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\AbstractResult; /** @@ -32,21 +31,11 @@ class Raw extends AbstractResult } /** - * @param HttpResponseInterface|ResponseInterface $response - * @return $this - */ - protected function render(ResponseInterface $response) - { - return $this->renderHttpResponse($response); - } - - /** - * @param HttpResponseInterface $httpResponse - * @return $this + * {@inheritdoc} */ - private function renderHttpResponse(HttpResponseInterface $httpResponse) + protected function render(HttpResponseInterface $response) { - $httpResponse->setBody($this->contents); + $response->setBody($this->contents); return $this; } } diff --git a/lib/internal/Magento/Framework/Controller/Result/Redirect.php b/lib/internal/Magento/Framework/Controller/Result/Redirect.php index 7ac3415294a..5dd727ca0b0 100644 --- a/lib/internal/Magento/Framework/Controller/Result/Redirect.php +++ b/lib/internal/Magento/Framework/Controller/Result/Redirect.php @@ -8,7 +8,6 @@ namespace Magento\Framework\Controller\Result; use Magento\Framework\App; use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; -use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\AbstractResult; /** @@ -92,21 +91,11 @@ class Redirect extends AbstractResult } /** - * @param HttpResponseInterface|ResponseInterface $response - * @return $this - */ - protected function render(ResponseInterface $response) - { - return $this->renderHttpResponse($response); - } - - /** - * @param HttpResponseInterface $httpResponse - * @return $this + * {@inheritdoc} */ - private function renderHttpResponse(HttpResponseInterface $httpResponse) + protected function render(HttpResponseInterface $response) { - $httpResponse->setRedirect($this->url); + $response->setRedirect($this->url); return $this; } } diff --git a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/JsonTest.php b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/JsonTest.php index 2d43a4a72af..0d38131ce01 100644 --- a/lib/internal/Magento/Framework/Controller/Test/Unit/Result/JsonTest.php +++ b/lib/internal/Magento/Framework/Controller/Test/Unit/Result/JsonTest.php @@ -24,13 +24,14 @@ class JsonTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Framework\Translate\InlineInterface|\PHPUnit_Framework_MockObject_MockObject * $translateInline */ - $translateInline = $this->getMock(\Magento\Framework\Translate\InlineInterface::class, [], [], '', false); + $translateInline = $this->getMock(\Magento\Framework\Translate\InlineInterface::class); $translateInline->expects($this->any())->method('processResponseBody')->with($json, true)->will( $this->returnValue($translatedJson) ); - $response = $this->getMock(\Magento\Framework\App\Response\Http::class, ['representJson'], [], '', false); - $response->expects($this->atLeastOnce())->method('representJson')->with($json)->will($this->returnSelf()); + $response = $this->getMock(\Magento\Framework\App\Response\HttpInterface::class); + $response->expects($this->atLeastOnce())->method('setHeader')->with('Content-Type', 'application/json', true); + $response->expects($this->atLeastOnce())->method('setBody')->with($json); /** @var \Magento\Framework\Controller\Result\Json $resultJson */ $resultJson = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this)) diff --git a/lib/internal/Magento/Framework/View/Result/Layout.php b/lib/internal/Magento/Framework/View/Result/Layout.php index fd4061551ac..a71f5402f89 100644 --- a/lib/internal/Magento/Framework/View/Result/Layout.php +++ b/lib/internal/Magento/Framework/View/Result/Layout.php @@ -102,7 +102,7 @@ class Layout extends AbstractResult /** * Get layout instance for current page * - * @return \Magento\Framework\View\Layout + * @return \Magento\Framework\View\LayoutInterface */ public function getLayout() { @@ -153,19 +153,10 @@ class Layout extends AbstractResult /** * Render current layout * - * @param HttpResponseInterface|ResponseInterface $response + * @param HttpResponseInterface|ResponseInterface $httpResponse * @return $this */ - public function renderResult(ResponseInterface $response) - { - return $this->renderHttpResult($response); - } - - /** - * @param HttpResponseInterface $httpResponse - * @return $this - */ - private function renderHttpResult(HttpResponseInterface $httpResponse) + public function renderResult(ResponseInterface $httpResponse) { \Magento\Framework\Profiler::start('LAYOUT'); \Magento\Framework\Profiler::start('layout_render'); @@ -182,25 +173,13 @@ class Layout extends AbstractResult } /** - * Render current layout - * - * @param HttpResponseInterface|ResponseInterface $response - * @return $this - */ - protected function render(ResponseInterface $response) - { - return $this->renderHttpResponse($response); - } - - /** - * @param HttpResponseInterface $httpResponse - * @return $this + * {@inheritdoc} */ - private function renderHttpResponse(HttpResponseInterface $httpResponse) + protected function render(HttpResponseInterface $response) { $output = $this->layout->getOutput(); $this->translateInline->processResponseBody($output); - $httpResponse->appendBody($output); + $response->appendBody($output); return $this; } } diff --git a/lib/internal/Magento/Framework/View/Result/Page.php b/lib/internal/Magento/Framework/View/Result/Page.php index 6bec99cfe30..6fc7fcbf9f2 100644 --- a/lib/internal/Magento/Framework/View/Result/Page.php +++ b/lib/internal/Magento/Framework/View/Result/Page.php @@ -8,7 +8,6 @@ namespace Magento\Framework\View\Result; use Magento\Framework; use Magento\Framework\App\Response\HttpInterface as HttpResponseInterface; -use Magento\Framework\App\ResponseInterface; use Magento\Framework\View; /** @@ -220,19 +219,9 @@ class Page extends Layout } /** - * @param HttpResponseInterface|ResponseInterface $response - * @return $this - */ - protected function render(ResponseInterface $response) - { - return $this->renderHttpResponse($response); - } - - /** - * @param HttpResponseInterface $httpResponse - * @return $this + * {@inheritdoc} */ - private function renderHttpResponse(HttpResponseInterface $httpResponse) + protected function render(HttpResponseInterface $response) { $this->pageConfig->publicBuild(); if ($this->getPageLayout()) { @@ -254,9 +243,9 @@ class Page extends Layout $this->assign('layoutContent', $output); $output = $this->renderPage(); $this->translateInline->processResponseBody($output); - $httpResponse->appendBody($output); + $response->appendBody($output); } else { - parent::render($httpResponse); + parent::render($response); } return $this; } -- GitLab From 4176384134b26cc203a4e6d7eec465b48e33e34d Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Thu, 11 Aug 2016 10:11:33 +0300 Subject: [PATCH 267/838] MAGETWO-54134: CE module depends on EE code - Moved RMA plugins from DHL, Fedex, Usps modules to RMA module - Covered moved plugins by unit tests --- .../Rma/Edit/Tab/General/Shippingmethod.php | 39 -------- app/code/Magento/Dhl/composer.json | 3 +- app/code/Magento/Dhl/etc/di.xml | 4 - .../Rma/Edit/Tab/General/Shippingmethod.php | 39 -------- app/code/Magento/Fedex/composer.json | 3 - app/code/Magento/Fedex/etc/di.xml | 13 --- .../Tab/General/Shipping/Packaging/Plugin.php | 91 ------------------- app/code/Magento/Usps/etc/adminhtml/di.xml | 6 -- 8 files changed, 1 insertion(+), 197 deletions(-) delete mode 100644 app/code/Magento/Dhl/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php delete mode 100644 app/code/Magento/Fedex/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php delete mode 100644 app/code/Magento/Fedex/etc/di.xml delete mode 100644 app/code/Magento/Usps/Block/Rma/Adminhtml/Rma/Edit/Tab/General/Shipping/Packaging/Plugin.php diff --git a/app/code/Magento/Dhl/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php b/app/code/Magento/Dhl/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php deleted file mode 100644 index acc859ac8c2..00000000000 --- a/app/code/Magento/Dhl/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Dhl\Model\Plugin\Rma\Block\Adminhtml\Rma\Edit\Tab\General; - -/** - * Checkout cart shipping block plugin - */ -class Shippingmethod -{ - /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface - */ - protected $_scopeConfig; - - /** - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ - public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) - { - $this->_scopeConfig = $scopeConfig; - } - - /** - * @param \Magento\Framework\DataObject $subject - * @param bool $result - * @return bool - */ - public function afterCanDisplayCustomValue(\Magento\Framework\DataObject $subject, $result) - { - $carrierCode = $subject->getShipment()->getCarrierCode(); - if (!$carrierCode) { - return (bool)$result || false; - } - return (bool)$result || (bool)$carrierCode == \Magento\Dhl\Model\Carrier::CODE; - } -} diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json index cab7f39538d..e88cd535952 100644 --- a/app/code/Magento/Dhl/composer.json +++ b/app/code/Magento/Dhl/composer.json @@ -16,8 +16,7 @@ "lib-libxml": "*" }, "suggest": { - "magento/module-checkout": "100.2.*", - "magento/module-rma": "100.2.*" + "magento/module-checkout": "100.2.*" }, "type": "magento2-module", "version": "100.2.0-dev", diff --git a/app/code/Magento/Dhl/etc/di.xml b/app/code/Magento/Dhl/etc/di.xml index 25b90ce8850..a215c2e8218 100644 --- a/app/code/Magento/Dhl/etc/di.xml +++ b/app/code/Magento/Dhl/etc/di.xml @@ -9,8 +9,4 @@ <type name="Magento\Checkout\Block\Cart\LayoutProcessor"> <plugin name="checkout_cart_shipping_dhl" type="Magento\Dhl\Model\Plugin\Checkout\Block\Cart\Shipping"/> </type> - <type name="Magento\Rma\Block\Adminhtml\Rma\Edit\Tab\General\Shippingmethod"> - <plugin name="rma_tab_shippingmethod_dhl" - type="Magento\Dhl\Model\Plugin\Rma\Block\Adminhtml\Rma\Edit\Tab\General\Shippingmethod"/> - </type> </config> diff --git a/app/code/Magento/Fedex/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php b/app/code/Magento/Fedex/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php deleted file mode 100644 index 7319a6e9e69..00000000000 --- a/app/code/Magento/Fedex/Model/Plugin/Rma/Block/Adminhtml/Rma/Edit/Tab/General/Shippingmethod.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Fedex\Model\Plugin\Rma\Block\Adminhtml\Rma\Edit\Tab\General; - -/** - * Checkout cart shipping block plugin - */ -class Shippingmethod -{ - /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface - */ - protected $_scopeConfig; - - /** - * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig - */ - public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig) - { - $this->_scopeConfig = $scopeConfig; - } - - /** - * @param \Magento\Framework\DataObject $subject - * @param bool $result - * @return bool - */ - public function afterCanDisplayCustomValue(\Magento\Framework\DataObject $subject, $result) - { - $carrierCode = $subject->getShipment()->getCarrierCode(); - if (!$carrierCode) { - return (bool)$result || false; - } - return (bool)$result || (bool)$carrierCode == \Magento\Fedex\Model\Carrier::CODE; - } -} diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json index 07c988e280d..d27d5c1c60d 100644 --- a/app/code/Magento/Fedex/composer.json +++ b/app/code/Magento/Fedex/composer.json @@ -14,9 +14,6 @@ "magento/framework": "100.2.*", "lib-libxml": "*" }, - "suggest": { - "magento/module-rma": "100.2.*" - }, "type": "magento2-module", "version": "100.2.0-dev", "license": [ diff --git a/app/code/Magento/Fedex/etc/di.xml b/app/code/Magento/Fedex/etc/di.xml deleted file mode 100644 index 454beffacba..00000000000 --- a/app/code/Magento/Fedex/etc/di.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\Rma\Block\Adminhtml\Rma\Edit\Tab\General\Shippingmethod"> - <plugin name="rma_tab_shippingmethod_fedex" - type="Magento\Fedex\Model\Plugin\Rma\Block\Adminhtml\Rma\Edit\Tab\General\Shippingmethod"/> - </type> -</config> diff --git a/app/code/Magento/Usps/Block/Rma/Adminhtml/Rma/Edit/Tab/General/Shipping/Packaging/Plugin.php b/app/code/Magento/Usps/Block/Rma/Adminhtml/Rma/Edit/Tab/General/Shipping/Packaging/Plugin.php deleted file mode 100644 index b0a91da7a07..00000000000 --- a/app/code/Magento/Usps/Block/Rma/Adminhtml/Rma/Edit/Tab/General/Shipping/Packaging/Plugin.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Usps\Block\Rma\Adminhtml\Rma\Edit\Tab\General\Shipping\Packaging; - -use Magento\Framework\App\RequestInterface; -use Magento\Usps\Helper\Data as UspsHelper; -use Magento\Usps\Model\Carrier; - -/** - * Rma block plugin - */ -class Plugin -{ - /** - * Usps helper - * - * @var \Magento\Usps\Helper\Data - */ - protected $uspsHelper; - - /** - * Request - * - * @var \Magento\Framework\App\RequestInterface - */ - protected $request; - - /** - * Construct - * - * @param \Magento\Usps\Helper\Data $uspsHelper - * @param \Magento\Framework\App\RequestInterface $request - */ - public function __construct(UspsHelper $uspsHelper, RequestInterface $request) - { - $this->uspsHelper = $uspsHelper; - $this->request = $request; - } - - /** - * Add rule to isGirthAllowed() method - * - * @param \Magento\Framework\DataObject $subject $subject - * @param bool $result - * @return bool - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function afterIsGirthAllowed(\Magento\Framework\DataObject $subject, $result) - { - return $result && $this->uspsHelper->displayGirthValue($this->request->getParam('method')); - } - - /** - * Add rule to isGirthAllowed() method - * - * @param \Magento\Framework\DataObject $subject - * @param \Closure $proceed - * @return array - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function aroundCheckSizeAndGirthParameter(\Magento\Framework\DataObject $subject, \Closure $proceed) - { - $carrier = $subject->getCarrier(); - $size = $subject->getSourceSizeModel(); - - $girthEnabled = false; - $sizeEnabled = false; - if ($carrier && isset($size[0]['value'])) { - if (in_array( - key($subject->getContainers()), - [Carrier::CONTAINER_NONRECTANGULAR, Carrier::CONTAINER_VARIABLE] - ) - ) { - $girthEnabled = true; - } - - if (in_array( - key($subject->getContainers()), - [Carrier::CONTAINER_NONRECTANGULAR, Carrier::CONTAINER_RECTANGULAR, Carrier::CONTAINER_VARIABLE] - ) - ) { - $sizeEnabled = true; - } - } - - return [$girthEnabled, $sizeEnabled]; - } -} diff --git a/app/code/Magento/Usps/etc/adminhtml/di.xml b/app/code/Magento/Usps/etc/adminhtml/di.xml index f098306c6e9..f60c4d8eb58 100644 --- a/app/code/Magento/Usps/etc/adminhtml/di.xml +++ b/app/code/Magento/Usps/etc/adminhtml/di.xml @@ -6,12 +6,6 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\Rma\Block\Adminhtml\Rma\Edit\Tab\General\Shipping\Packaging"> - <arguments> - <argument name="sourceSizeModel" xsi:type="object">Magento\Usps\Model\Source\Size</argument> - </arguments> - <plugin name="usps" type="Magento\Usps\Block\Rma\Adminhtml\Rma\Edit\Tab\General\Shipping\Packaging\Plugin"/> - </type> <type name="Magento\Shipping\Block\Adminhtml\Order\Packaging"> <arguments> <argument name="sourceSizeModel" xsi:type="object">Magento\Usps\Model\Source\Size</argument> -- GitLab From 55b46715ec99346883c64b7a4315961ff7363594 Mon Sep 17 00:00:00 2001 From: Rykh Oleksandr <orykh@magento.com> Date: Thu, 11 Aug 2016 10:49:13 +0300 Subject: [PATCH 268/838] MTA-3464: Merge Domain Functional Bamboo Plan - removed domain from group tag --- .../Test/TestCase/GlobalSearchEntityTest.php | 2 +- .../BraintreeSettlementReportTest.php | 2 +- .../CheckoutWithBraintreePaypalCartTest.php | 2 +- ...heckoutWithBraintreePaypalMinicartTest.php | 2 +- ...ateOnlineCreditMemoBraintreePaypalTest.php | 2 +- .../TestCase/InvoicePayPalBraintreeTest.php | 2 +- .../OnePageCheckoutWith3dSecureTest.php | 2 +- ...OnePageCheckoutWithBraintreePaypalTest.php | 2 +- ...veUseDeleteVaultForPaypalBraintreeTest.php | 2 +- .../UseVaultWith3dSecureOnCheckoutTest.php | 2 +- .../CreateBundleProductEntityTest.php | 2 +- .../UpdateBundleProductEntityTest.php | 2 +- .../Category/CreateCategoryEntityTest.php | 2 +- .../Category/DeleteCategoryEntityTest.php | 2 +- .../Category/UpdateCategoryEntityTest.php | 2 +- .../Product/AddCompareProductsTest.php | 2 +- .../Product/AddToCartCrossSellTest.php | 2 +- .../Product/ClearAllCompareProductsTest.php | 2 +- .../Product/CreateSimpleProductEntityTest.php | 2 +- .../CreateVirtualProductEntityTest.php | 2 +- .../Product/DeleteCompareProductsTest.php | 2 +- .../Product/DeleteProductEntityTest.php | 2 +- .../Product/DuplicateProductEntityTest.php | 2 +- .../Product/MassProductUpdateTest.php | 2 +- .../Product/NavigateRelatedProductsTest.php | 2 +- .../Product/NavigateUpSellProductsTest.php | 2 +- .../ProductTypeSwitchingOnCreationTest.php | 2 +- .../ProductTypeSwitchingOnUpdateTest.php | 2 +- .../Product/UpdateSimpleProductEntityTest.php | 2 +- .../UpdateVirtualProductEntityTest.php | 2 +- .../ValidateOrderOfProductTypeTest.php | 2 +- .../CreateAttributeSetEntityTest.php | 2 +- ...ductAttributeEntityFromProductPageTest.php | 2 +- .../CreateProductAttributeEntityTest.php | 2 +- ...AssignedToTemplateProductAttributeTest.php | 2 +- .../DeleteAttributeSetTest.php | 2 +- .../DeleteProductAttributeEntityTest.php | 2 +- .../DeleteSystemProductAttributeTest.php | 2 +- ...UsedInConfigurableProductAttributeTest.php | 2 +- .../UpdateAttributeSetTest.php | 2 +- .../UpdateProductAttributeEntityTest.php | 2 +- .../TestCase/ApplyCatalogPriceRulesTest.php | 2 +- .../CreateCatalogPriceRuleEntityTest.php | 2 +- .../DeleteCatalogPriceRuleEntityTest.php | 2 +- .../UpdateCatalogPriceRuleEntityTest.php | 2 +- .../TestCase/AdvancedSearchEntityTest.php | 2 +- .../TestCase/CreateSearchTermEntityTest.php | 2 +- .../TestCase/DeleteSearchTermEntityTest.php | 2 +- .../MassDeleteSearchTermEntityTest.php | 2 +- .../Test/TestCase/SearchEntityResultsTest.php | 2 +- .../SuggestSearchingResultEntityTest.php | 2 +- .../TestCase/UpdateSearchTermEntityTest.php | 2 +- .../AddProductsToShoppingCartEntityTest.php | 2 +- .../DeleteProductFromMiniShoppingCartTest.php | 2 +- .../DeleteProductsFromShoppingCartTest.php | 2 +- .../Test/TestCase/OnePageCheckoutTest.php | 2 +- ...eProductFromMiniShoppingCartEntityTest.php | 2 +- .../Test/TestCase/UpdateShoppingCartTest.php | 2 +- .../Test/TestCase/CreateTermEntityTest.php | 2 +- .../Test/TestCase/DeleteTermEntityTest.php | 2 +- .../Test/TestCase/UpdateTermEntityTest.php | 2 +- .../TestCase/CreateCmsBlockEntityTest.php | 2 +- .../Test/TestCase/CreateCmsPageEntityTest.php | 2 +- .../CreateCmsPageRewriteEntityTest.php | 2 +- .../TestCase/DeleteCmsBlockEntityTest.php | 2 +- .../Test/TestCase/DeleteCmsPageEntityTest.php | 2 +- .../DeleteCmsPageUrlRewriteEntityTest.php | 2 +- .../TestCase/UpdateCmsBlockEntityTest.php | 2 +- .../Test/TestCase/UpdateCmsPageEntityTest.php | 2 +- .../UpdateCmsPageRewriteEntityTest.php | 2 +- .../CreateConfigurableProductEntityTest.php | 2 +- .../UpdateConfigurableProductEntityTest.php | 2 +- .../TestCase/EditCurrencySymbolEntityTest.php | 2 +- .../ResetCurrencySymbolEntityTest.php | 2 +- .../Customer/Test/TestCase/ApplyVatIdTest.php | 2 +- .../TestCase/ChangeCustomerPasswordTest.php | 2 +- .../CreateCustomerGroupEntityTest.php | 2 +- .../CreateExistingCustomerFrontendEntity.php | 2 +- .../TestCase/DeleteCustomerAddressTest.php | 2 +- .../DeleteCustomerBackendEntityTest.php | 2 +- .../DeleteCustomerGroupEntityTest.php | 2 +- .../DeleteSystemCustomerGroupTest.php | 2 +- .../TestCase/ForgotPasswordOnFrontendTest.php | 2 +- .../TestCase/MassAssignCustomerGroupTest.php | 2 +- .../MassDeleteCustomerBackendEntityTest.php | 2 +- .../RegisterCustomerFrontendEntityTest.php | 2 +- .../UpdateCustomerFrontendEntityTest.php | 2 +- .../UpdateCustomerGroupEntityTest.php | 2 +- .../VerifyDisabledCustomerGroupFieldTest.php | 2 +- .../Test/TestCase/CreateCurrencyRateTest.php | 2 +- .../CreateDownloadableProductEntityTest.php | 2 +- .../UpdateDownloadableProductEntityTest.php | 2 +- .../TestCase/CheckoutWithGiftMessagesTest.php | 2 +- .../CreateGroupedProductEntityTest.php | 2 +- .../UpdateGroupedProductEntityTest.php | 2 +- .../Install/Test/TestCase/InstallTest.php | 2 +- .../ActivateIntegrationEntityTest.php | 2 +- .../TestCase/CreateIntegrationEntityTest.php | 2 +- ...reateIntegrationWithDuplicatedNameTest.php | 2 +- .../TestCase/DeleteIntegrationEntityTest.php | 2 +- ...ReAuthorizeTokensIntegrationEntityTest.php | 2 +- .../TestCase/UpdateIntegrationEntityTest.php | 2 +- .../Test/TestCase/FilterProductListTest.php | 2 +- .../Msrp/Test/TestCase/ApplyMapTest.php | 2 +- .../ActionNewsletterTemplateEntityTest.php | 2 +- .../CreateNewsletterTemplateEntityTest.php | 2 +- .../PreviewNewsletterTemplateEntityTest.php | 2 +- .../TestCase/UpdateNewsletterTemplateTest.php | 2 +- .../ExpressCheckoutFromProductPageTest.php | 2 +- .../ExpressCheckoutFromShoppingCartTest.php | 2 +- .../TestCase/ExpressCheckoutOnePageTest.php | 2 +- ...extExpressCheckoutFromShoppingCartTest.php | 2 +- .../InContextExpressOnePageCheckoutTest.php | 2 +- .../Test/TestCase/AddProductVideoTest.php | 2 +- .../Test/TestCase/DeleteProductVideoTest.php | 2 +- .../Test/TestCase/UpdateProductVideoTest.php | 2 +- .../AbandonedCartsReportEntityTest.php | 2 +- .../BestsellerProductsReportEntityTest.php | 2 +- .../CustomerReviewReportEntityTest.php | 2 +- .../CustomersOrderCountReportEntityTest.php | 2 +- .../CustomersOrderTotalReportEntityTest.php | 2 +- .../DownloadProductsReportEntityTest.php | 2 +- .../LowStockProductsReportEntityTest.php | 2 +- .../TestCase/NewAccountsReportEntityTest.php | 2 +- .../OrderedProductsReportEntityTest.php | 2 +- .../ProductReviewReportEntityTest.php | 2 +- .../ProductsInCartReportEntityTest.php | 2 +- .../TestCase/SalesCouponReportEntityTest.php | 2 +- .../TestCase/SalesInvoiceReportEntityTest.php | 2 +- .../TestCase/SalesOrderReportEntityTest.php | 2 +- .../TestCase/SalesRefundsReportEntityTest.php | 2 +- .../TestCase/SalesTaxReportEntityTest.php | 2 +- .../TestCase/SearchTermsReportEntityTest.php | 2 +- .../ViewedProductsReportEntityTest.php | 2 +- .../CreateProductRatingEntityTest.php | 2 +- .../CreateProductReviewBackendEntityTest.php | 2 +- .../CreateProductReviewFrontendEntityTest.php | 2 +- .../DeleteProductRatingEntityTest.php | 2 +- ...anageProductReviewFromCustomerPageTest.php | 2 +- .../MassActionsProductReviewEntityTest.php | 2 +- .../ModerateProductReviewEntityTest.php | 2 +- ...teProductReviewEntityOnProductPageTest.php | 2 +- .../UpdateProductReviewEntityTest.php | 2 +- .../TestCase/AssignCustomOrderStatusTest.php | 2 +- .../Test/TestCase/CancelCreatedOrderTest.php | 2 +- .../TestCase/CreateCreditMemoEntityTest.php | 2 +- .../CreateCustomOrderStatusEntityTest.php | 2 +- .../Test/TestCase/CreateInvoiceEntityTest.php | 2 +- .../CreateOnlineInvoiceEntityTest.php | 2 +- .../Test/TestCase/CreateOrderBackendTest.php | 2 +- .../Test/TestCase/HoldCreatedOrderTest.php | 2 +- .../Test/TestCase/MassOrdersUpdateTest.php | 2 +- ...MoveLastOrderedProductsOnOrderPageTest.php | 2 +- .../MoveProductsInComparedOnOrderPageTest.php | 2 +- ...ecentlyComparedProductsOnOrderPageTest.php | 2 +- ...eRecentlyViewedProductsOnOrderPageTest.php | 2 +- ...oveShoppingCartProductsOnOrderPageTest.php | 2 +- .../TestCase/PrintOrderFrontendGuestTest.php | 2 +- .../Test/TestCase/ReorderOrderEntityTest.php | 2 +- .../UnassignCustomOrderStatusTest.php | 2 +- .../TestCase/UpdateCustomOrderStatusTest.php | 2 +- .../ApplySeveralSalesRuleEntityTest.php | 2 +- .../TestCase/CreateSalesRuleEntityTest.php | 2 +- .../TestCase/DeleteSalesRuleEntityTest.php | 2 +- .../TestCase/UpdateSalesRuleEntityTest.php | 2 +- .../TestCase/CreateSynonymGroupEntityTest.php | 2 +- .../TestCase/DeleteSynonymGroupEntityTest.php | 2 +- .../TestCase/MergeSynonymGroupEntityTest.php | 2 +- .../TestCase/UpdateSynonymGroupEntityTest.php | 2 +- .../Test/TestCase/EnableDisableModuleTest.php | 2 +- .../TestCase/CreateShipmentEntityTest.php | 2 +- .../Test/TestCase/CreateSitemapEntityTest.php | 2 +- .../Test/TestCase/DeleteSitemapEntityTest.php | 2 +- .../Test/TestCase/CreateStoreEntityTest.php | 2 +- .../TestCase/CreateStoreGroupEntityTest.php | 2 +- .../Test/TestCase/CreateWebsiteEntityTest.php | 2 +- .../Test/TestCase/DeleteStoreEntityTest.php | 2 +- .../TestCase/DeleteStoreGroupEntityTest.php | 2 +- .../Test/TestCase/DeleteWebsiteEntityTest.php | 2 +- .../Test/TestCase/UpdateStoreEntityTest.php | 2 +- .../TestCase/UpdateStoreGroupEntityTest.php | 2 +- .../Test/TestCase/UpdateWebsiteEntityTest.php | 2 +- .../Test/TestCase/SwaggerUiForRestApiTest.php | 2 +- .../TestCase/ApplyTaxBasedOnVatIdTest.php | 2 +- .../Test/TestCase/CreateTaxRateEntityTest.php | 2 +- .../Test/TestCase/CreateTaxRuleEntityTest.php | 2 +- .../Test/TestCase/DeleteTaxRateEntityTest.php | 2 +- .../Test/TestCase/DeleteTaxRuleEntityTest.php | 2 +- .../Tax/Test/TestCase/TaxCalculationTest.php | 2 +- .../Test/TestCase/TaxWithCrossBorderTest.php | 2 +- .../Test/TestCase/UpdateTaxRateEntityTest.php | 2 +- .../Test/TestCase/UpdateTaxRuleEntityTest.php | 2 +- .../Ui/Test/TestCase/GridFilteringTest.php | 2 +- .../Test/TestCase/GridFullTextSearchTest.php | 2 +- .../Ui/Test/TestCase/GridSortingTest.php | 2 +- .../CreateCategoryRewriteEntityTest.php | 2 +- .../CreateCustomUrlRewriteEntityTest.php | 2 +- .../CreateProductUrlRewriteEntityTest.php | 2 +- .../DeleteCategoryUrlRewriteEntityTest.php | 2 +- .../DeleteCustomUrlRewriteEntityTest.php | 2 +- .../DeleteProductUrlRewriteEntityTest.php | 2 +- .../UpdateCategoryUrlRewriteEntityTest.php | 2 +- .../UpdateCustomUrlRewriteEntityTest.php | 2 +- .../UpdateProductUrlRewriteEntityTest.php | 2 +- .../TestCase/CreateAdminUserEntityTest.php | 2 +- .../CreateAdminUserRoleEntityTest.php | 2 +- .../TestCase/DeleteAdminUserEntityTest.php | 2 +- .../TestCase/DeleteUserRoleEntityTest.php | 2 +- .../Test/TestCase/LockAdminUserEntityTest.php | 2 +- ...lAccessTokensForAdminWithoutTokensTest.php | 2 +- .../TestCase/UpdateAdminUserEntityTest.php | 2 +- .../UpdateAdminUserRoleEntityTest.php | 2 +- .../UserLoginAfterChangingPermissionsTest.php | 2 +- .../CreateCustomVariableEntityTest.php | 2 +- .../DeleteCustomVariableEntityTest.php | 2 +- .../UpdateCustomVariableEntityTest.php | 2 +- .../TestCase/CreateVaultOrderBackendTest.php | 2 +- .../TestCase/DeleteSavedCreditCardTest.php | 2 +- .../Test/TestCase/ReorderUsingVaultTest.php | 2 +- .../Test/TestCase/UseVaultOnCheckoutTest.php | 2 +- .../Test/TestCase/CreateTaxWithFptTest.php | 2 +- .../Test/TestCase/CreateWidgetEntityTest.php | 2 +- .../Test/TestCase/DeleteWidgetEntityTest.php | 2 +- .../AddProductToWishlistEntityTest.php | 2 +- ...CartFromCustomerWishlistOnFrontendTest.php | 2 +- ...ProductInCustomerWishlistOnBackendTest.php | 2 +- ...roductInCustomerWishlistOnFrontendTest.php | 2 +- ...oductFromCustomerWishlistOnBackendTest.php | 2 +- ...leteProductsFromWishlistOnFrontendTest.php | 2 +- ...eProductFromShoppingCartToWishlistTest.php | 2 +- .../Test/TestCase/ShareWishlistEntityTest.php | 2 +- ...ProductInCustomerWishlistOnBackendTest.php | 2 +- .../{domain_mx_category.xml => category.xml} | 0 .../TestSuite/InjectableTests/domain_cs.xml | 27 ------------------- .../TestSuite/InjectableTests/domain_mx.xml | 23 ---------------- .../TestSuite/InjectableTests/domain_ps.xml | 27 ------------------- 236 files changed, 232 insertions(+), 309 deletions(-) rename dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/{domain_mx_category.xml => category.xml} (100%) delete mode 100644 dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_cs.xml delete mode 100644 dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_mx.xml delete mode 100644 dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_ps.xml diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php index 4261e9fa82d..a75c3f94ccd 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/GlobalSearchEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Fill in data according dataset * 4. Perform assertions * - * @group Search_Core_(MX) + * @group Search_Core * @ZephyrId MAGETWO-28457 */ class GlobalSearchEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php index 9b1bb894b0d..9828d21b630 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/BraintreeSettlementReportTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Scenario; * 12. Find transaction for latest order. * 13. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-48162 */ class BraintreeSettlementReportTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php index 26c1c6f0797..a0bf482705f 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalCartTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Scenario; * 8. Select payment method * 12. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-39363 */ class CheckoutWithBraintreePaypalCartTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php index e7b36898991..f0f0291b33e 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CheckoutWithBraintreePaypalMinicartTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Scenario; * 8. Select payment method * 12. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-39359 */ class CheckoutWithBraintreePaypalMinicartTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php index 0631acd511f..6554845d5ff 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/CreateOnlineCreditMemoBraintreePaypalTest.php @@ -17,7 +17,7 @@ use Magento\Mtf\TestCase\Scenario; * 3. Create credit memo. * 4. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-48689, MAGETWO-48698 */ class CreateOnlineCreditMemoBraintreePaypalTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php index d2db16e5be4..70489848865 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/InvoicePayPalBraintreeTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Scenario; * 6. Open Invoices tab. * 7. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-48614, MAGETWO-48615 */ class InvoicePayPalBraintreeTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php index 090487489be..f7171a775a2 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWith3dSecureTest.php @@ -31,7 +31,7 @@ use Magento\Mtf\TestCase\Scenario; * 12. Click 'Submit' to place order. * 13. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-46479 */ class OnePageCheckoutWith3dSecureTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php index ee954b671be..706725c7375 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/OnePageCheckoutWithBraintreePaypalTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Scenario; * 11. Click 'Proceed purchase' in popup. * 12. Perform assertions. * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-47805 * @ZephyrId MAGETWO-47810 */ diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php index 58496d34f97..f6813b74e40 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.php @@ -35,7 +35,7 @@ use Magento\Mtf\TestCase\Scenario; * 15. Click *Delete* button on appeared pop up. * 16. Perform assertions. * * - * @group Braintree_(CS) + * @group Braintree * @ZephyrId MAGETWO-54838, MAGETWO-54843, MAGETWO-54844" */ class SaveUseDeleteVaultForPaypalBraintreeTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php index 5377506cff9..13b8240d4c4 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.php @@ -35,7 +35,7 @@ use Magento\Mtf\TestCase\Scenario; * 16. Click 'Submit' to place order. * 17. Perform assertions. * - * @group One_Page_Checkout_(CS) + * @group One_Page_Checkout * @ZephyrId MAGETWO-55310 */ class UseVaultWith3dSecureOnCheckoutTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php index 4a064d840c9..ac2c977f88b 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/CreateBundleProductEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save product * 6. Verify created product * - * @group Bundle_Product_(CS) + * @group Bundle_Product * @ZephyrId MAGETWO-24118 */ class CreateBundleProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php index 1348507c2dd..bf17d216bcf 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/UpdateBundleProductEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save". * 6. Perform asserts * - * @group Bundle_Product_(MX) + * @group Bundle_Product * @ZephyrId MAGETWO-26195 */ class UpdateBundleProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php index 00fabef8456..d458ffeb224 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save category * 6. Verify created category * - * @group Category_Management_(MX) + * @group Category_Management * @ZephyrId MAGETWO-23411 */ class CreateCategoryEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php index db166505fab..e7b613f43af 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/DeleteCategoryEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete" button. * 5. Perform asserts. * - * @group Category_Management_(MX) + * @group Category_Management * @ZephyrId MAGETWO-23303 */ class DeleteCategoryEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php index 66b09b2f4b7..ab8b03e8bfe 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/UpdateCategoryEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\Fixture\FixtureFactory; * 5. Save * 6. Perform asserts * - * @group Category_Management_(MX) + * @group Category_Management * @ZephyrId MAGETWO-23290 */ class UpdateCategoryEntityTest extends Injectable 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 1de71d149ee..131163311bc 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 @@ -22,7 +22,7 @@ use Magento\Catalog\Test\Page\Product\CatalogProductCompare; * 4. Navigate to compare page(click "compare product" link at the top of the page). * 5. Perform all asserts. * - * @group Compare_Products_(MX) + * @group Compare_Products * @ZephyrId MAGETWO-25843 */ class AddCompareProductsTest extends AbstractCompareProductsTest diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php index 4a1ef07b454..59f45bc004b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/AddToCartCrossSellTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\Fixture\InjectableFixture; * 2. Verify Cross-sell block on checkout page. * * @ZephyrId MAGETWO-12390 - * @group Cross-sells_(MX) + * @group Cross-sells */ class AddToCartCrossSellTest extends AbstractProductPromotedProductsTest { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php index a3fec9105ac..ebc7360fe00 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ClearAllCompareProductsTest.php @@ -21,7 +21,7 @@ use Magento\Customer\Test\Page\CustomerAccountIndex; * 4. Click "Clear All" icon under the left menu tabs. * 5. Perform assertions. * - * @group Compare_Products_(MX) + * @group Compare_Products * @ZephyrId MAGETWO-25961 */ class ClearAllCompareProductsTest extends AbstractCompareProductsTest diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php index 76b013d5696..c0cab5ef8e6 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save Product. * 6. Perform appropriate assertions. * - * @group Products_(CS) + * @group Products * @ZephyrId MAGETWO-23414 */ class CreateSimpleProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php index 6ee67d04cf9..290275ef4e8 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save product. * 6. Verify created product. * - * @group Virtual_Product_(CS) + * @group Virtual_Product * @ZephyrId MAGETWO-23417 */ class CreateVirtualProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php index 75a419df04c..7026b757bb7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteCompareProductsTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\Fixture\FixtureFactory; * 3. Click (X) icon near the $product from dataset. * 4. Perform assertions. * - * @group Compare_Products_(MX) + * @group Compare_Products * @ZephyrId MAGETWO-26161 */ class DeleteCompareProductsTest extends AbstractCompareProductsTest diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php index 617c3d45310..1a0c46b146f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DeleteProductEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Submit form. * 6. Perform asserts. * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-23272 */ class DeleteProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php index d7d98b19df3..bdf90b5df3b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/DuplicateProductEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Save & Duplicate". * 5. Perform asserts. * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-23294 */ class DuplicateProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php index 7ab1ffaa6e0..f7fd82e3342 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php @@ -28,7 +28,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductActionAttributeEdit; * 9. Click on the "Save" button. * 10. Perform asserts. * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-21128 */ class MassProductUpdateTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php index a8792ba6c8e..49fec0876e4 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateRelatedProductsTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\Fixture\InjectableFixture; * 3. Verify checkout cart. * * @ZephyrId MAGETWO-12392 - * @group Related_Products_(MX) + * @group Related_Products */ class NavigateRelatedProductsTest extends AbstractProductPromotedProductsTest { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php index ee375563241..37d8c9dc91d 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/NavigateUpSellProductsTest.php @@ -17,7 +17,7 @@ use Magento\Mtf\Fixture\InjectableFixture; * 1. Navigate through up-sell products. * * @ZephyrId MAGETWO-12391 - * @group Up-sells_(MX) + * @group Up-sells */ class NavigateUpSellProductsTest extends AbstractProductPromotedProductsTest { diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php index 0a29696e463..c8189cd50eb 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save * 6. Perform all assertions * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-29398 */ class ProductTypeSwitchingOnCreationTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php index 066045e4836..7c134c2902c 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Save * 7. Perform all assertions * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-29633 */ class ProductTypeSwitchingOnUpdateTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php index 0a8b9f0bfb7..f68ec539c62 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save". * 6. Perform asserts. * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-23544, MAGETWO-21125 */ class UpdateSimpleProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php index 64d3b68a988..ddd788d7ee1 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateVirtualProductEntityTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save". * 6. Perform asserts. * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-26204 */ class UpdateVirtualProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php index 148b1d2b8bf..a8c375ba2d8 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ValidateOrderOfProductTypeTest.php @@ -14,7 +14,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex; * 1. Login to backend. * 2. Navigate to PRODUCTS -> Catalog. * - * @group Products_(MX) + * @group Products * @ZephyrId MAGETWO-37146 */ class ValidateOrderOfProductTypeTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php index c66fdfd5a49..d3bd8f44adb 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateAttributeSetEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Save new Attribute Set. * 7. Verify created Attribute Set. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-25104 */ class CreateAttributeSetEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php index 1f335e2a590..0a85628c5e7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityFromProductPageTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Scenario; * 8. Save product. * 7. Perform appropriate assertions. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-30528 */ class CreateProductAttributeEntityFromProductPageTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php index 49d3d3fddad..22325ead5f5 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/CreateProductAttributeEntityTest.php @@ -17,7 +17,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Save Product Attribute. * 6. Perform appropriate assertions. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-24767 */ class CreateProductAttributeEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php index bf43658890c..11958cc2c1e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAssignedToTemplateProductAttributeTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click on the "Delete Attribute" button. * 6. Perform all assertions. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-26011 */ class DeleteAssignedToTemplateProductAttributeTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php index ac0d6566b94..b097dc4681b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteAttributeSetTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click 'Delete' button. * 5. Perform all assertions. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-25473 */ class DeleteAttributeSetTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php index 3cf6395a08c..737a086dbb7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteProductAttributeEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click on the "Delete Attribute" button. * 6. Perform all assertions. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-24998 */ class DeleteProductAttributeEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php index 456eadfa1fe..20fee003a57 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteSystemProductAttributeTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click on line with search results. * 5. Perform assertion. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-24771 */ class DeleteSystemProductAttributeTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php index 0ddaa387804..baf9a238c6b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/DeleteUsedInConfigurableProductAttributeTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click on the "Delete Attribute" button. * 6. Perform asserts. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-26652 */ class DeleteUsedInConfigurableProductAttributeTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php index 51cb635bd6f..af6b5747819 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateAttributeSetTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Save Attribute Set. * 8. Preform all assertions. * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-26251 */ class UpdateAttributeSetTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php index b669b940ac2..399b918078f 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/ProductAttribute/UpdateProductAttributeEntityTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save Attribute' button * 6. Perform all assertions * - * @group Product_Attributes_(MX) + * @group Product_Attributes * @ZephyrId MAGETWO-23459 */ class UpdateProductAttributeEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php index 3ce7dc159c0..4a4c6a25321 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/ApplyCatalogPriceRulesTest.php @@ -23,7 +23,7 @@ use Magento\CatalogRule\Test\Page\Adminhtml\CatalogRuleEdit; * 2. Create simple product. * 3. Perform all assertions. * - * @group Catalog_Price_Rules_(MX) + * @group Catalog_Price_Rules * @ZephyrId MAGETWO-24780 */ class ApplyCatalogPriceRulesTest extends AbstractCatalogRuleEntityTest diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php index c46cc72bf79..f5efc258fbd 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.php @@ -20,7 +20,7 @@ use Magento\Customer\Test\Fixture\CustomerGroup; * 5. Save rule. * 6. Perform appropriate assertions. * - * @group Catalog_Price_Rules_(MX) + * @group Catalog_Price_Rules * @ZephyrId MAGETWO-24341 */ class CreateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php index 9bc68a959bf..a2d0ff9500d 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/DeleteCatalogPriceRuleEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click on the "Delete" button. * 5. Perform all assertions. * - * @group Catalog_Price_Rules_(MX) + * @group Catalog_Price_Rules * @ZephyrId MAGETWO-25211 */ class DeleteCatalogPriceRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php index b045460053d..8ca54baed57 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\Util\Command\Cli\Cron; * 6. Create simple product with category. * 7. Perform all asserts. * - * @group Catalog_Price_Rules_(MX) + * @group Catalog_Price_Rules * @ZephyrId MAGETWO-25187 */ class UpdateCatalogPriceRuleEntityTest extends AbstractCatalogRuleEntityTest diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php index 7014196fa0d..a3e5a4ba850 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Search" button * 5. Perform all asserts * - * @group Search_Frontend_(MX) + * @group Search_Frontend * @ZephyrId MAGETWO-24729 */ class AdvancedSearchEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php index f92d55a9b85..f6ffd84c0b4 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Save the Search Term. * 8. Perform all assertions. * - * @group Search_Terms_(MX) + * @group Search_Terms * @ZephyrId MAGETWO-26165 */ class CreateSearchTermEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php index f7d4114b748..ab5fb5f5bcd 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete Search" button * 5. Perform all assertions * - * @group Search_Terms_(MX) + * @group Search_Terms * @ZephyrId MAGETWO-26491 */ class DeleteSearchTermEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php index 85afc4013dc..5f41d187564 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Submit form * 6. Perform all assertions * - * @group Search_Terms_(MX) + * @group Search_Terms * @ZephyrId MAGETWO-26599 */ class MassDeleteSearchTermEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php index 7d0a6179ed1..c845e7f0bfe 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php @@ -19,7 +19,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Input test data into "search field" and press Enter key. * 3. Perform all assertions. * - * @group Search_Frontend_(MX) + * @group Search_Frontend * @ZephyrId MAGETWO-25095 */ class SearchEntityResultsTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php index 376214dc004..42c1683a6cd 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Input in "Search" field test data. * 3. Perform asserts. * - * @group Search_Frontend_(CS) + * @group Search_Frontend * @ZephyrId MAGETWO-24671 */ class SuggestSearchingResultEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php index f50293bbe5e..291f71322de 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/UpdateSearchTermEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Save the Search Term. * 8. Perform all assertions. * - * @group Search_Terms_(MX) + * @group Search_Terms * @ZephyrId MAGETWO-26100 */ class UpdateSearchTermEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php index 6de035b5ca3..0733d778b96 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Add to cart test product * 4. Perform all asserts * - * @group Shopping_Cart_(CS) + * @group Shopping_Cart * @ZephyrId MAGETWO-25382 */ class AddProductsToShoppingCartEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php index 2e2b286dc32..f2a809656ed 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductFromMiniShoppingCartTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click Ok * 5. Perform all assertions * - * @group Mini_Shopping_Cart_(CS) + * @group Mini_Shopping_Cart * @ZephyrId MAGETWO-29104 */ class DeleteProductFromMiniShoppingCartTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php index c53d3e0a2bd..ae48e6e6b79 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/DeleteProductsFromShoppingCartTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Click 'Remove item' button from Shopping Cart for each product(s) * 3. Perform all asserts * - * @group Shopping_Cart_(CS) + * @group Shopping_Cart * @ZephyrId MAGETWO-25218 */ class DeleteProductsFromShoppingCartTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php index 6e00ad65420..58d0c23f227 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.php @@ -32,7 +32,7 @@ use Magento\Mtf\TestCase\Scenario; * 13. Place order. * 14. Perform assertions. * - * @group One_Page_Checkout_(CS) + * @group One_Page_Checkout * @ZephyrId MAGETWO-27485, MAGETWO-12412, MAGETWO-12429 * @ZephyrId MAGETWO-12444, MAGETWO-12848, MAGETWO-12849, MAGETWO-12850 */ 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 806b72c23e2..62d773a6637 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 @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click Update. * 5. Perform all assertions. * - * @group Mini_Shopping_Cart_(CS) + * @group Mini_Shopping_Cart * @ZephyrId MAGETWO-29812 */ class UpdateProductFromMiniShoppingCartEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php index 8b4fc487832..809688cd828 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateShoppingCartTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Update Shopping Cart" button * 5. Perform all assertion from dataset * - * @group Shopping_Cart_(CS) + * @group Shopping_Cart * @ZephyrId MAGETWO-25081 */ class UpdateShoppingCartTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php index d8cc5935c37..21f48abef96 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/CreateTermEntityTest.php @@ -19,7 +19,7 @@ use Magento\Mtf\TestCase\Scenario; * 4. Save * 5. Perform all assertions * - * @group Terms_and_Conditions_(CS) + * @group Terms_and_Conditions * @ZephyrId MAGETWO-29586, MAGETWO-32499 */ class CreateTermEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php index d88e01a6c8a..2c65150aa69 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/DeleteTermEntityTest.php @@ -19,7 +19,7 @@ use Magento\Mtf\TestCase\Scenario; * 3. Click on 'Delete' button. * 4. Perform all assertions. * - * @group Terms_and_Conditions_(CS) + * @group Terms_and_Conditions * @ZephyrId MAGETWO-29687 */ class DeleteTermEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php index 816208c578b..277f38e0c7e 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/TestCase/UpdateTermEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Scenario; * 4. Save * 5. Perform all assertions * - * @group Terms_and_Conditions_(CS) + * @group Terms_and_Conditions * @ZephyrId MAGETWO-29635 */ class UpdateTermEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php index fcd78e0543d..7e3c3f0ebb3 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php @@ -19,7 +19,7 @@ use Magento\Cms\Test\Fixture\CmsBlock; * 4. Fill data according to dataset. * 5. Perform all assertions. * - * @group CMS_Content_(PS) + * @group CMS_Content * @ZephyrId MAGETWO-25578 */ class CreateCmsBlockEntityTest extends AbstractCmsBlockEntityTest diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php index 398201e7376..f5035a2eaf7 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save CMS Page. * 6. Verify created CMS Page. * - * @group CMS_Content_(PS) + * @group CMS_Content * @ZephyrId MAGETWO-25580 */ class CreateCmsPageEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php index fcd031f4037..29652554007 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Save Rewrite. * 8. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-24847 */ class CreateCmsPageRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php index b0257e0cd5e..ad2ae5689c9 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php @@ -24,7 +24,7 @@ use Magento\Catalog\Test\Fixture\Category; * 4. Click "Delete Block". * 5. Perform all assertions. * - * @group CMS_Content_(PS) + * @group CMS_Content * @ZephyrId MAGETWO-25698 */ class DeleteCmsBlockEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php index 777345ca2cf..25225917014 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete Page" button. * 5. Perform all assertions. * - * @group CMS_Content_(PS) + * @group CMS_Content * @ZephyrId MAGETWO-23291 */ class DeleteCmsPageEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php index b08bb14d4d0..68d0ae54125 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Delete Redirect. * 5. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-25915 */ class DeleteCmsPageUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php index fb9ac37993a..8fa92fba59f 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php @@ -20,7 +20,7 @@ use Magento\Cms\Test\Fixture\CmsBlock; * 4. Fill data according to dataset. * 5. Perform all assertions. * - * @group CMS_Content_(PS) + * @group CMS_Content * @ZephyrId MAGETWO-25941 */ class UpdateCmsBlockEntityTest extends AbstractCmsBlockEntityTest diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php index b0b67a1e75c..b16f4384f27 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save' CMS Page. * 6. Perform asserts. * - * @group CMS_Content_(PS) + * @group CMS_Content * @ZephyrId MAGETWO-25186 */ class UpdateCmsPageEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php index 8ebf371d73e..43fd7e69ac3 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save Redirect. * 6. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-26173 */ class UpdateCmsPageRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php index 93a19cf6874..e72b98c93b9 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.php @@ -33,7 +33,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Save product * 7. Perform all assertions * - * @group Configurable_Product_(MX) + * @group Configurable_Product * @ZephyrId MAGETWO-26041 */ class CreateConfigurableProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php index f08484f605e..7ff2be303d6 100644 --- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/UpdateConfigurableProductEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Save product. * 6. Perform all assertions. * - * @group Configurable_Product_(MX) + * @group Configurable_Product * @ZephyrId MAGETWO-29916 */ class UpdateConfigurableProductEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php index e53a403e8ca..14a9d6f283b 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/EditCurrencySymbolEntityTest.php @@ -20,7 +20,7 @@ use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity; * 4. Click 'Save Currency Symbols' button * 5. Perform all asserts. * - * @group Currency_(PS) + * @group Currency * @ZephyrId MAGETWO-26600 */ class EditCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest diff --git a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php index 1a6b9b8094f..8740b0000ff 100644 --- a/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/CurrencySymbol/Test/TestCase/ResetCurrencySymbolEntityTest.php @@ -21,7 +21,7 @@ use Magento\CurrencySymbol\Test\Fixture\CurrencySymbolEntity; * 4. Click 'Save Currency Symbols' button * 5. Perform all asserts. * - * @group Currency_(PS) + * @group Currency * @ZephyrId MAGETWO-26638 */ class ResetCurrencySymbolEntityTest extends AbstractCurrencySymbolEntityTest diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php index 88d51e97350..8f5b671fec9 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ApplyVatIdTest.php @@ -25,7 +25,7 @@ use Magento\Customer\Test\Fixture\Customer; * 5. Save Customer Address. * 6. Perform assertions. * - * @group VAT_ID_(CS) + * @group VAT_ID * @ZephyrId MAGETWO-12447 */ class ApplyVatIdTest extends AbstractApplyVatIdTest diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php index a01c6d34069..a8774bb9956 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ChangeCustomerPasswordTest.php @@ -26,7 +26,7 @@ use Magento\Customer\Test\Page\CustomerAccountLogin; * 4. Fill form according to data set and save * 5. Perform all assertions * - * @group Customer_Account_(CS) + * @group Customer_Account * @ZephyrId MAGETWO-29411 */ class ChangeCustomerPasswordTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php index 63e679b78b8..64051195daa 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5.Click "Save Customer Group" button. * 6.Perform all assertions. * - * @group Customer_Groups_(CS) + * @group Customer_Groups * @ZephyrId MAGETWO-23422 */ class CreateCustomerGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php index 15a132e59b0..7ac9b5284b3 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateExistingCustomerFrontendEntity.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click 'Create account' button. * 5. Perform assertions. * - * @group Customer_Account_(CS) + * @group Customer_Account * @ZephyrId MAGETWO-23545 */ class CreateExistingCustomerFrontendEntity extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php index aa4a6e2c7ce..61771665c05 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerAddressTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Delete second address - click 'Delete Address' button. * 5. Perform all assertions. * - * @group Customers_(CS) + * @group Customers * @ZephyrId MAGETWO-28066 */ class DeleteCustomerAddressTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php index ed2a080882e..3e6916eb2b2 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Fill in data according to dataset * 5. Perform all assertions according to dataset * - * @group Customers_(CS) + * @group Customers * @ZephyrId MAGETWO-24764 */ class DeleteCustomerBackendEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php index d0bf918b5e0..f8c426a3efb 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerGroupEntityTest.php @@ -24,7 +24,7 @@ use Magento\Customer\Test\Fixture\Customer; * 5. Confirm in pop-up. * 6. Perform all assertions. * - * @group Customer_Groups_(CS) + * @group Customer_Groups * @ZephyrId MAGETWO-25243 */ class DeleteCustomerGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php index 6176e5f2d42..a9e09d24fb0 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteSystemCustomerGroupTest.php @@ -17,7 +17,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Select system Customer Group specified in data set from grid. * 4. Perform all assertions. * - * @group Customer_Groups_(CS) + * @group Customer_Groups * @ZephyrId MAGETWO-53576 */ class DeleteSystemCustomerGroupTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php index d95a215fb91..d257805dc54 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/ForgotPasswordOnFrontendTest.php @@ -20,7 +20,7 @@ use Magento\Customer\Test\Page\CustomerAccountForgotPassword; * 3. Click forgot password button. * 4. Check forgot password message. * - * @group Customer_(CS) + * @group Customer * @ZephyrId MAGETWO-37145 */ class ForgotPasswordOnFrontendTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php index 8369533ed43..f7448024b93 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassAssignCustomerGroupTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Submit" button * 7. Perform all assertions * - * @group Customer_Groups_(CS), Customers_(CS) + * @group Customer_Groups, Customers * @ZephyrId MAGETWO-27892 */ class MassAssignCustomerGroupTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php index 43efeaaaca4..598a4465724 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/MassDeleteCustomerBackendEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click Submit button * 6. Perform all assertions according to dataset * - * @group Customers_(CS) + * @group Customers * @ZephyrId MAGETWO-26848 */ class MassDeleteCustomerBackendEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php index 2dcd57ac0eb..b2bad9a3bd3 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/RegisterCustomerFrontendEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click 'Create account' button. * 5. Perform assertions. * - * @group Customer_Account_(CS) + * @group Customer_Account * @ZephyrId MAGETWO-23546 */ class RegisterCustomerFrontendEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php index 888067ac0ed..34338371d45 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerFrontendEntityTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Fill fields with test data and save. * 7. Perform all assertions. * - * @group Customer_Account_(CS) + * @group Customer_Account * @ZephyrId MAGETWO-25925 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php index 377e1b1fd4b..7fda95c0be7 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerGroupEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save Customer Group" button * 6. Perform all assertions * - * @group Customer_Groups_(CS) + * @group Customer_Groups * @ZephyrId MAGETWO-25536 */ class UpdateCustomerGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php index c29189cd14a..dfe3afca43f 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.php @@ -17,7 +17,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Select system Customer Group specified in data set from grid. * 4. Perform all assertions. * - * @group Customer_Groups_(CS) + * @group Customer_Groups * @ZephyrId MAGETWO-52481 */ class VerifyDisabledCustomerGroupFieldTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php index ccd3add8e90..4d397bde28b 100644 --- a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php +++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php @@ -24,7 +24,7 @@ use Magento\CurrencySymbol\Test\Page\Adminhtml\SystemCurrencyIndex; * 4. Click on 'Save Currency Rates' button. * 5. Perform assertions. * - * @group Localization_(PS) + * @group Localization * @ZephyrId MAGETWO-36824 */ class CreateCurrencyRateTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php index 8ef9493728d..7cc3fd6375c 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Save product. * 7. Verify created product. * - * @group Downloadable_Product_(MX) + * @group Downloadable_Product * @ZephyrId MAGETWO-23425 */ class CreateDownloadableProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php index 72797c10db5..276cc08e8ef 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save". * 6. Perform asserts. * - * @group Downloadable_Product_(MX) + * @group Downloadable_Product * @ZephyrId MAGETWO-24775 */ class UpdateDownloadableProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php index 8b151965212..e33adb68be4 100644 --- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php +++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/TestCase/CheckoutWithGiftMessagesTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Scenario; * 4. Complete Checkout steps * 5. Perform all asserts * - * @group Gift_Messages_(CS) + * @group Gift_Messages * @ZephyrId MAGETWO-28978 */ class CheckoutWithGiftMessagesTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php index df5f8485f0b..bbe3b5ace0e 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Save the Product. * 8. Perform assertions. * - * @group Grouped_Product_(MX) + * @group Grouped_Product * @ZephyrId MAGETWO-24877 */ class CreateGroupedProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php index fa90eeca3e6..224fcbd3170 100644 --- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/UpdateGroupedProductEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save the Product. * 6. Perform all assertions. * - * @group Grouped_Product_(MX) + * @group Grouped_Product * @ZephyrId MAGETWO-26462 */ class UpdateGroupedProductEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php index 427bec35281..f7931b03e3d 100644 --- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php +++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php @@ -37,7 +37,7 @@ use Magento\Install\Test\Constraint\AssertAdminUriAutogenerated; * 12. Click "Next" and on the "Step 6: Install" page click "Install Now" button. * 13. Perform assertions. * - * @group Installer_and_Upgrade/Downgrade_(PS) + * @group Installer_and_Upgrade/Downgrade * @ZephyrId MAGETWO-31431 */ class InstallTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php index 36403cb8e25..b8fa9638dc2 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ActivateIntegrationEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Click on the "Activate" link near required integration. * 4. Perform all assertions. * - * @group Web_API_Framework_(PS) + * @group Web_API_Framework * @ZephyrId MAGETWO-26119 */ class ActivateIntegrationEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php index a8ab81ded70..d7bd5b93ef0 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save" button. * 6. Perform all assertions. * - * @group Web_API_Framework_(PS) + * @group Web_API_Framework * @ZephyrId MAGETWO-26009, MAGETWO-16755, MAGETWO-16819, MAGETWO-16820 */ class CreateIntegrationEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php index 91e18055a87..52d6dea9a13 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/CreateIntegrationWithDuplicatedNameTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 8. Click "Save" button * 9. Perform all assertions * - * @group Web_API_Framework_(PS) + * @group Web_API_Framework * @ZephyrId MAGETWO-16756 */ class CreateIntegrationWithDuplicatedNameTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php index 1915399a87f..c2878aeda72 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/DeleteIntegrationEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete" button. * 5. Perform all assertions. * - * @group Web_API_Framework_(PS) + * @group Web_API_Framework * @ZephyrId MAGETWO-26058 */ class DeleteIntegrationEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php index c844d8a34e9..2af446b97b0 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/ReAuthorizeTokensIntegrationEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click Done. * 5. Perform assertions. * - * @group Integrations_(PS) + * @group Integrations * @ZephyrId MAGETWO-29648 */ class ReAuthorizeTokensIntegrationEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php index b1e52bdf725..a349ba38650 100644 --- a/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Integration/Test/TestCase/UpdateIntegrationEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save" button. * 6. Perform all assertions. * - * @group Web_API_Framework_(PS) + * @group Web_API_Framework * @ZephyrId MAGETWO-26102 */ class UpdateIntegrationEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php index 6e4ed481161..543880aea12 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Create product with created category. * 3. Perform all assertions. * - * @group Layered_Navigation_(MX) + * @group Layered_Navigation * @ZephyrId MAGETWO-12419 */ class FilterProductListTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php b/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php index 855bbfb5136..f6f9c912f35 100644 --- a/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php +++ b/dev/tests/functional/tests/app/Magento/Msrp/Test/TestCase/ApplyMapTest.php @@ -13,7 +13,7 @@ use Magento\Mtf\TestCase\Injectable; * 1. Create product. * 2. Perform all assertions. * - * @group MAP_(MX) + * @group MAP * @ZephyrId MAGETWO-12430, MAGETWO-12847 */ class ApplyMapTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php index 0fe5fdab870..a79ea3995ee 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/ActionNewsletterTemplateEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Select action in action dropdown for created template according to dataset * 5. Perform all assertions * - * @group Newsletters_(MX) + * @group Newsletters * @ZephyrId MAGETWO-27043 */ class ActionNewsletterTemplateEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php index d1a6b448e60..62fb186a3c6 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save. * 6. Perform asserts. * - * @group Newsletters_(MX) + * @group Newsletters * @ZephyrId MAGETWO-23302 */ class CreateNewsletterTemplateEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php index 6ab2d72c265..2ec44f0e303 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/PreviewNewsletterTemplateEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Preview Template" button at the top of the page * 5. Perform all assertions * - * @group Newsletters_(MX) + * @group Newsletters * @ZephyrId MAGETWO-51979 */ class PreviewNewsletterTemplateEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php index 5bc3a932442..f6d29ba6a84 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/UpdateNewsletterTemplateTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save Template' button * 6. Perform asserts * - * @group Newsletters_(MX) + * @group Newsletters * @ZephyrId MAGETWO-29427 */ class UpdateNewsletterTemplateTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php index 92f009ef449..c8fb3e4f30f 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromProductPageTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Process checkout via PayPal. * 6. Perform asserts. * - * @group PayPal_(CS) + * @group PayPal * @ZephyrId MAGETWO-12415 */ class ExpressCheckoutFromProductPageTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php index ec6c87b0e3f..7fc35ff1eb6 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutFromShoppingCartTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Process checkout via PayPal. * 6. Perform asserts. * - * @group PayPal_(CS) + * @group PayPal * @ZephyrId MAGETWO-12414 */ class ExpressCheckoutFromShoppingCartTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php index 67715c1c575..b40adf986db 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/ExpressCheckoutOnePageTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Process checkout via PayPal. * 6. Perform asserts. * - * @group PayPal_(CS) + * @group PayPal * @ZephyrId MAGETWO-12413, MAGETWO-14359, MAGETWO-12996 */ class ExpressCheckoutOnePageTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php index 453ab8f96af..07f03b1c931 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressCheckoutFromShoppingCartTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Click "Cancel". * 6. Perform asserts. * - * @group PayPal_(CS) + * @group PayPal * @ZephyrId MAGETWO-47213 */ class InContextExpressCheckoutFromShoppingCartTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php index b9e794bd8f4..ff06e6b1026 100644 --- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/InContextExpressOnePageCheckoutTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Click "Cancel". * 6. Perform asserts. * - * @group PayPal_(CS) + * @group PayPal * @ZephyrId MAGETWO-47261 */ class InContextExpressOnePageCheckoutTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php index 297b6f6de18..c5175df4ad0 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/AddProductVideoTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Save" button on product page. * 7. Perform asserts. * - * @group ProductVideo_(MX) + * @group ProductVideo * @ZephyrId MAGETWO-43673 */ class AddProductVideoTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php index 7ebf84fb47c..ebc5e0ccf93 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/DeleteProductVideoTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 8. Click "Save" button on product page. * 9. Perform asserts. * - * @group ProductVideo_(MX) + * @group ProductVideo * @ZephyrId MAGETWO-43660 */ class DeleteProductVideoTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php index 6821eceef3f..30df076817d 100644 --- a/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php +++ b/dev/tests/functional/tests/app/Magento/ProductVideo/Test/TestCase/UpdateProductVideoTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 9. Click "Save" button on product page * 10. Perform asserts. * - * @group ProductVideo_(MX) + * @group ProductVideo * @ZephyrId MAGETWO-43664, @ZephyrId MAGETWO-43656, @ZephyrId MAGETWO-43661, @ZephyrId MAGETWO-43663 */ class UpdateProductVideoTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php index 4ad19088c68..5930e63b9d3 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/AbandonedCartsReportEntityTest.php @@ -27,7 +27,7 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView; * 3. Click "Reset Filter". * 4. Perform all assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28558 */ class AbandonedCartsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php index f4236137c0e..3eb5237eddd 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/BestsellerProductsReportEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Show report". * 5. Perform all assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28222 */ class BestsellerProductsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php index ef5eec6e4e9..1e3b2c12b44 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomerReviewReportEntityTest.php @@ -33,7 +33,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Click Show Reviews * 4. Perform appropriate assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-27555 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php index 5b43485a8a6..cacb6e5a329 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderCountReportEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click button Refresh * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28521 */ class CustomersOrderCountReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php index 13c92bfde8a..c366cedb3c3 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/CustomersOrderTotalReportEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click button Refresh * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28358 */ class CustomersOrderTotalReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php index ec7a335f0d5..97dc365d623 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/DownloadProductsReportEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Go to Reports > Products > Downloads. * 3. Perform all assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28823 */ class DownloadProductsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php index 32d6c457f2a..0dd87bde327 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/LowStockProductsReportEntityTest.php @@ -18,7 +18,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Open Reports > Low Stock. * 3. Perform appropriate assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-27193 */ class LowStockProductsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php index b3f0f2c244f..bb5f8644d43 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/NewAccountsReportEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Refresh button". * 5. Perform all assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-27742 */ class NewAccountsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php index bd231c47a35..7d0d13862e7 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/OrderedProductsReportEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Refresh button" * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28200 */ class OrderedProductsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php index b92a5fba541..9848da36df7 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ProductReviewReportEntityTest.php @@ -19,7 +19,7 @@ use Magento\Mtf\TestCase\Injectable; * 2. Navigate to the Reports>Reviews>By Products * 3. Perform appropriate assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-27223 */ class ProductReviewReportEntityTest extends Injectable 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 d8b71bf1105..148c0a69cec 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 @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Add product to cart as unregistered customer * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-27952 */ class ProductsInCartReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php index fb1da56b4a9..0d59b989fc2 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesCouponReportEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Show report" * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28190 */ class SalesCouponReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php index e58aaafb7f9..3ebfd4746a8 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesInvoiceReportEntityTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Show Report" * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-29216 */ class SalesInvoiceReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php index a35e3cef096..c1eb4e8b35c 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesOrderReportEntityTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Show Report" * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-29136 */ class SalesOrderReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php index e2ba3387a18..692e9024a22 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesRefundsReportEntityTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click button Show Report * 5. Perform Asserts * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-29348 */ class SalesRefundsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php index 2c9d818c777..0d5249ef4d0 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SalesTaxReportEntityTest.php @@ -32,7 +32,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Show report". * 5. Perform all assertions. * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-28515 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php index 85b202ea21b..1175942452f 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Navigate to: Reports > Search Terms. * 4. Perform appropriate assertions. * - * @group Search_Terms_(MX) + * @group Search_Terms * @ZephyrId MAGETWO-27106 */ class SearchTermsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php index 8550dffcf1b..4e410e38d10 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php @@ -26,7 +26,7 @@ use Magento\Cms\Test\Page\CmsIndex; * 4. Click "Show report" * 5. Perform all assertions * - * @group Reports_(MX) + * @group Reports * @ZephyrId MAGETWO-27954 */ class ViewedProductsReportEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php index 047ae6521e5..648de4bf401 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save Rating. * 6. Perform asserts. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-23331 */ class CreateProductRatingEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php index 1677daf7820..aeeff3480e4 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewBackendEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Save Review" button. * 7. Perform Asserts. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-26476 */ class CreateProductReviewBackendEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php index 73a5ee2dce6..2e764636789 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductReviewFrontendEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. click "Submit review". * 6. Perform all assertions. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-25519 */ class CreateProductReviewFrontendEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php index aee8ef840c6..316af940788 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Delete Rating' button. * 6. Perform all asserts. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-23276 */ class DeleteProductRatingEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php index 2f673bcfce4..fc582663562 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ManageProductReviewFromCustomerPageTest.php @@ -34,7 +34,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Click "Submit review". * 8. Perform all assertions. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-27625 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php index fb73765357a..027b299e710 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Submit" button. * 7. Perform Asserts. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-26618 */ class MassActionsProductReviewEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php index a97b9961c97..dbe89b387e6 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ModerateProductReviewEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save. * 6. Perform all assertions. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-26768 */ class ModerateProductReviewEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php index e099a313164..9f343bdfc10 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityOnProductPageTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Save changes. * 7. Perform all assertions. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-27743 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php index 478dae48d35..a5901a6211a 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Submit review". * 6. Perform all assertions. * - * @group Reviews_and_Ratings_(MX) + * @group Reviews_and_Ratings * @ZephyrId MAGETWO-25604 */ class UpdateProductReviewEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php index 5898f9bce90..6d49174e069 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/AssignCustomOrderStatusTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Create Order. * 8. Perform all assertions from dataset. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-29382 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php index f1096549f8e..1779ad437c7 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Do cancel Order. * 5. Perform all assetions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28191 */ class CancelCreatedOrderTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php index c74c1c460e3..ed00a414bd0 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. On order's page click 'Refund offline' button. * 5. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-29116 */ class CreateCreditMemoEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php index 1dc12dc31f1..3dc689a3852 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save order status. * 6. Verify created order status. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-23412 */ class CreateCustomOrderStatusEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php index e4fe93a72e1..f62583583c3 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Submit Invoice' button. * 6. Perform assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28209 */ class CreateInvoiceEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php index ef2f4f038af..c3b00b4b7f7 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOnlineInvoiceEntityTest.php @@ -32,7 +32,7 @@ use Magento\Mtf\TestCase\Scenario; * 16. Click 'Submit Invoice' button. * 17. Perform assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-47010 */ class CreateOnlineInvoiceEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php index 1784204e8de..284a09f4233 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateOrderBackendTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Scenario; * 11. Submit Order. * 12. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28696 */ class CreateOrderBackendTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php index afd87907872..8b45a8a22ee 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/HoldCreatedOrderTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Do 'Hold' for Order. * 5. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28214 */ class HoldCreatedOrderTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php index 9eff5d2f8ce..4f62fa07bba 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Submit. * 5. Perform Asserts. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-27897 */ class MassOrdersUpdateTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php index cb64304341e..719ae586305 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveLastOrderedProductsOnOrderPageTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click Update Changes. * 6. Perform all assertions. * - * @group Customers_(CS), Order_Management_(CS) + * @group Customers, Order_Management * @ZephyrId MAGETWO-27640 */ class MoveLastOrderedProductsOnOrderPageTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php index 1997f0cc8c3..cedf2aeb71c 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveProductsInComparedOnOrderPageTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Update Changes'. * 6. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28050 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php index 3a2c1af1ef6..49487ff1b2e 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyComparedProductsOnOrderPageTest.php @@ -31,7 +31,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Update Changes'. * 6. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28109 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php index 1942a2f4ce3..d6a4b685e57 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MoveRecentlyViewedProductsOnOrderPageTest.php @@ -28,7 +28,7 @@ use Magento\Customer\Test\Fixture\Customer; * 10. Click Update Items and Qty's button. * 11. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-29723 */ class MoveRecentlyViewedProductsOnOrderPageTest extends Injectable 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 6238e41b9c3..21a13d782e0 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 @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click Update Changes. * 6. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28540 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php index 73eeb45164a..4e05d4025fc 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Scenario; * 5. Click on the "Print Order" button. * 6. Perform appropriate assertions.v * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-30253 */ class PrintOrderFrontendGuestTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php index 78f6cdb1354..60547dd9e03 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/ReorderOrderEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Scenario; * 4. Do 'Reorder' for placed order. * 5. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-29007 */ class ReorderOrderEntityTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php index 38b1a9ed562..de9939ce106 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UnassignCustomOrderStatusTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 3. Click "Unassign" for appropriate status. * 4. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-29450 */ class UnassignCustomOrderStatusTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php index 4e6e3c45d0a..e5da53b48b7 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/UpdateCustomOrderStatusTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save order status. * 6. Perform all assertions. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-29868 */ class UpdateCustomOrderStatusTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php index f706df29339..a5a554f7a18 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/ApplySeveralSalesRuleEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\Fixture\FixtureFactory; * 2. Apply all created rules. * 3. Perform all assertions. * - * @group Sales_Rules_(CS) + * @group Sales_Rules * @ZephyrId MAGETWO-45883 */ class ApplySeveralSalesRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php index b419c70b740..a07799d5f1e 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/CreateSalesRuleEntityTest.php @@ -27,7 +27,7 @@ use Magento\Customer\Test\Fixture\Customer; * 3. Create Cart Price rule according to dataset and click "Save" button. * 4. Perform asserts. * - * @group Shopping_Cart_Price_Rules_(CS) + * @group Shopping_Cart_Price_Rules * @ZephyrId MAGETWO-24855 */ class CreateSalesRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php index 374fc1bc542..7e0204a90d4 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/DeleteSalesRuleEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click 'Delete' button. * 5. Perform asserts. * - * @group Shopping_Cart_Price_Rules_(CS) + * @group Shopping_Cart_Price_Rules * @ZephyrId MAGETWO-24985 */ class DeleteSalesRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php index c4c698532e7..92dc0f4f839 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/UpdateSalesRuleEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save' button. * 6. Perform asserts. * - * @group Shopping_Cart_Price_Rules_(CS) + * @group Shopping_Cart_Price_Rules * @ZephyrId MAGETWO-24860 */ class UpdateSalesRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php index b4dedc18713..ce2222ba3dd 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/CreateSynonymGroupEntityTest.php @@ -22,7 +22,7 @@ use Magento\Search\Test\Fixture\SynonymGroup; * 4. Fill data according to dataset. * 5. Perform all assertions. * - * @group Search_(MX) + * @group Search * @ZephyrId MAGETWO-47681 */ class CreateSynonymGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php index e43feaf2c82..7e6ec5c14da 100755 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/DeleteSynonymGroupEntityTest.php @@ -22,7 +22,7 @@ use Magento\Search\Test\Fixture\SynonymGroup; * 3. Delete created Synonym Group * 4. Perform all assertions. * - * @group Search_(MX) + * @group Search * @ZephyrId MAGETWO-47683 */ class DeleteSynonymGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php index 8ae702052dc..4e9424a83be 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/MergeSynonymGroupEntityTest.php @@ -23,7 +23,7 @@ use Magento\Search\Test\Fixture\SynonymGroup; * 4. Fill data according to dataset. * 5. Perform all assertions. * - * @group Search_(MX) + * @group Search * @ZephyrId MAGETWO-47684 */ class MergeSynonymGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php index b7ae2e4b619..042a656339a 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Search/Test/TestCase/UpdateSynonymGroupEntityTest.php @@ -23,7 +23,7 @@ use Magento\Search\Test\Fixture\SynonymGroup; * 4. Fill data according to dataset. * 5. Perform all assertions. * - * @group Search_(MX) + * @group Search * @ZephyrId MAGETWO-49412 */ class UpdateSynonymGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/EnableDisableModuleTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/EnableDisableModuleTest.php index 5344e07cfc9..b68f25bd744 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/EnableDisableModuleTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/EnableDisableModuleTest.php @@ -37,7 +37,7 @@ use Magento\Setup\Test\Page\Adminhtml\SetupWizard; * 16. Check for Success message * 17. Return to "Web Setup Wizard". * - * @group Setup_(CS) + * @group Setup * @ZephyrId MAGETWO-43202 */ class EnableDisableModuleTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php b/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php index 46e5a781b8a..064bc2ec0ba 100644 --- a/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Shipping/Test/TestCase/CreateShipmentEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Submit Shipment' button. * 6. Perform all asserts. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-28708 */ class CreateShipmentEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php index 021503301fe..f820e92f9a5 100644 --- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save" button. * 6. Perform all assertions. * - * @group XML_Sitemap_(PS) + * @group XML_Sitemap * @ZephyrId MAGETWO-23277 */ class CreateSitemapEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php index f8c9aec04c3..e8f24bfccc0 100644 --- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete" button. * 5. Perform all assertions. * - * @group XML_Sitemap_(PS) + * @group XML_Sitemap * @ZephyrId MAGETWO-23296 */ class DeleteSitemapEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php index 80bef3298bb..804111c497c 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Fill data according to dataset * 5. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27647 */ class CreateStoreEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php index 08a38f28843..5d638d781d1 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateStoreGroupEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save Store" button * 6. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27345 */ class CreateStoreGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php index 8381849ecc4..766e030b3f6 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save Web Site" button * 6. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27665 */ class CreateWebsiteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php index 3c6db84612f..cbe261fe750 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Delete Store View" * 7. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27942 */ class DeleteStoreEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php index d672ee72bc5..e7ba27b44c1 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreGroupEntityTest.php @@ -31,7 +31,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Delete store" * 7. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27596 */ class DeleteStoreGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php index 7a7836f1b00..5d4af70cb03 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteWebsiteEntityTest.php @@ -31,7 +31,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click "Delete Web Site" * 7. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27723 */ class DeleteWebsiteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php index f4d83de1df4..38250d958bc 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Fill data according to dataset * 5. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27786 */ class UpdateStoreEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php index 4bdb0ebe71b..7e9143a5c91 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateStoreGroupEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save Store" button * 6. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27568 */ class UpdateStoreGroupEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php index 93017931d08..b187f058566 100644 --- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Save Web Site" button * 6. Perform all assertions * - * @group Store_Management_(PS) + * @group Store_Management * @ZephyrId MAGETWO-27690 */ class UpdateWebsiteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php b/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php index c8b96243a31..9246bdcd992 100644 --- a/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php +++ b/dev/tests/functional/tests/app/Magento/Swagger/Test/TestCase/SwaggerUiForRestApiTest.php @@ -21,7 +21,7 @@ use Magento\Swagger\Test\Page\SwaggerUiPage; * 5. Click operation name to show operation details * 6. Perform all assertions * - * @group Swagger_(PS) + * @group Swagger * @ZephyrId MAGETWO-41381, MAGETWO-41383 */ class SwaggerUiForRestApiTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php index 426b98e3c76..b35c566fd9b 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/ApplyTaxBasedOnVatIdTest.php @@ -31,7 +31,7 @@ use Magento\Customer\Test\TestCase\AbstractApplyVatIdTest; * 5. In 'Estimate Shipping and Tax' section specify destination and click 'Get a Quote' button. * 6. Perform assertions. * - * @group VAT_ID_(CS) + * @group VAT_ID * @ZephyrId MAGETWO-13436 */ class ApplyTaxBasedOnVatIdTest extends AbstractApplyVatIdTest diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php index 7508aeedc0c..f13cfc8d427 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRateEntityTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save Tax Rate. * 6. Perform all assertions. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-23286 */ class CreateTaxRateEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php index fe32777559e..9cfa401510b 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save Tax Rule. * 6. Perform all assertions. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-20913 */ class CreateTaxRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php index b4731d794d2..567e4860df1 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRateEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click Delete Rate * 5. Perform all assertions * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-23295 */ class DeleteTaxRateEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php index 72f7da60942..5553738b214 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/DeleteTaxRuleEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click on the "Delete Rule" button. * 5. Perform all assertions. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-20924 */ class DeleteTaxRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php index 95cd136be0e..14ef3cc293d 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxCalculationTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Scenario; * 12. Save tax configuration. * 13. Perform all assertions. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-27809 */ class TaxCalculationTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php index c1b182f68a1..9517ee063ce 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxWithCrossBorderTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Injectable; * 13. Register two customers on front end that will match two different rates * 14. Login with each customer and verify prices * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-29052 */ class TaxWithCrossBorderTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php index 5d545d2f84f..ff54451529a 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Click 'Save Rate' button. * 7. Perform asserts. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-23299 */ class UpdateTaxRateEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php index 6ba975ca3bc..bef2ede5733 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save' button. * 6. Perform all asserts. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-20996 */ class UpdateTaxRuleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php index 488cd1916d3..39a80b783a0 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFilteringTest.php @@ -22,7 +22,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid; * 3. Filter grid using provided columns * 5. Perform Asserts * - * @group Ui_(CS) + * @group Ui * @ZephyrId MAGETWO-41329 */ class GridFilteringTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php index 0174a0d8326..c0049f0cc2f 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridFullTextSearchTest.php @@ -22,7 +22,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid; * 3. Perfrom full text search * 5. Perform Asserts * - * @group Ui_(CS) + * @group Ui * @ZephyrId MAGETWO-41330 */ class GridFullTextSearchTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php index f60a81c9acc..d1f543c7b98 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/TestCase/GridSortingTest.php @@ -22,7 +22,7 @@ use Magento\Ui\Test\Block\Adminhtml\DataGrid; * 3. Sort grid using provided columns * 5. Perform Asserts * - * @group Ui_(CS) + * @group Ui * @ZephyrId MAGETWO-41328 */ class GridSortingTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php index f80bfe520f6..c3502924b56 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCategoryRewriteEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Save Rewrite. * 8. Verify created rewrite. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-24280 */ class CreateCategoryRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php index d200220b4b1..201a52ce5de 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 6. Save Rewrite. * 7. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-25474 */ class CreateCustomUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php index aa416e8cd8d..e333fdd2f06 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateProductUrlRewriteEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 7. Fill data according to dataset. * 8. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-25150 */ class CreateProductUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php index 0109e502180..0dcc9d8e198 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCategoryUrlRewriteEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Delete URL Rewrite. * 5. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-25086 */ class DeleteCategoryUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php index 417d137fd1f..4f4526d907b 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteCustomUrlRewriteEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Delete Redirect. * 5. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-26337 */ class DeleteCustomUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php index bfe2171e21d..9d8491b8afa 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewriteEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click 'Delete' button. * 5. Perform asserts. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-23287 */ class DeleteProductUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php index 458e9381ee4..2c7cf3ecbf4 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCategoryUrlRewriteEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save' button. * 6. Perform all asserts. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-24838 */ class UpdateCategoryUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php index 57660226ba5..04eb7fd5aa8 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateCustomUrlRewriteEntityTest.php @@ -24,7 +24,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save Redirect. * 6. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-25784 */ class UpdateCustomUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php index 1610666be0d..1f9c09fcb5f 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.php @@ -25,7 +25,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Fill data according to dataset. * 5. Perform all assertions. * - * @group URL_Rewrites_(MX) + * @group URL_Rewrites * @ZephyrId MAGETWO-24819 */ class UpdateProductUrlRewriteEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php index 7e0da18c990..2003bb4b277 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php @@ -23,7 +23,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save user * 6. Perform assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-25699 */ class CreateAdminUserEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php index 4176ade9a19..42dfaf10b93 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save role * 6. Perform assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-23413 */ class CreateAdminUserRoleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php index eea19670d5a..57de56c7f56 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete User" button * 5. Perform all assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-23416 */ class DeleteAdminUserEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php index c32c63e16b4..c3f0d766406 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click "Delete Role" button * 5. Perform all assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-23926 */ class DeleteUserRoleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php index 88ccb829a89..a6074b3f5ac 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LockAdminUserEntityTest.php @@ -24,7 +24,7 @@ use Magento\User\Test\Fixture\User; * 3. "You did not sign in correctly or your account is temporarily disabled." appears after each login attempt. * 4. Perform all assertions. * - * @group AuthN_&_AuthZ_(PS) + * @group AuthN_&_AuthZ * @ZephyrId MAGETWO-12386 */ class LockAdminUserEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php index 0a2b6a8d151..f570d179cd2 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/RevokeAllAccessTokensForAdminWithoutTokensTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click Ok on popup window. * 6. Perform all asserts. * - * @group Web_API_Framework_(PS) + * @group Web_API_Framework * @ZephyrId MAGETWO-29675 */ class RevokeAllAccessTokensForAdminWithoutTokensTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php index 8ea332373a5..79c58c434e2 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Save user * 6. Perform all assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-24345 */ class UpdateAdminUserEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php index 40c5f48864c..aaf3a42dc1d 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php @@ -27,7 +27,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Fill in data according to data set * 5. Perform all assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-24768 */ class UpdateAdminUserRoleEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php index 98c7e8a27d7..5eb73d2087e 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UserLoginAfterChangingPermissionsTest.php @@ -35,7 +35,7 @@ use Magento\Mtf\TestCase\Injectable; * 13. Log in using new admin user (before the bug was fixed, it was impossible to log in from the first attempt) * 14. Perform assertions * - * @group ACL_(PS) + * @group ACL * @ZephyrId MAGETWO-28828 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php index c9cdee72fdf..ccb14663571 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/CreateCustomVariableEntityTest.php @@ -20,7 +20,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click 'Save' button. * 6. Perform all asserts. * - * @group Variables_(PS) + * @group Variables * @ZephyrId MAGETWO-23293 */ class CreateCustomVariableEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php index 79b9a359bcb..6b3e819eaf9 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/DeleteCustomVariableEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Click 'Delete' button. * 5. Perform asserts. * - * @group Variables_(PS) + * @group Variables * @ZephyrId MAGETWO-25535 */ class DeleteCustomVariableEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php index be1765e573a..6e9631c7a95 100644 --- a/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Variable/Test/TestCase/UpdateCustomVariableEntityTest.php @@ -29,7 +29,7 @@ use Magento\Mtf\TestCase\Injectable; * 8. Save Custom variable using correspond saveActions. * 9. Perform all assertions. * - * @group Variables_(PS) + * @group Variables * @ZephyrId MAGETWO-26104 */ class UpdateCustomVariableEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php index 474b81ccac0..3c306280215 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/CreateVaultOrderBackendTest.php @@ -30,7 +30,7 @@ use Magento\Mtf\TestCase\Scenario; * 15. Select any available payment token. * 16. Place order. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-48127, MAGETWO-48091 */ class CreateVaultOrderBackendTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php index ea06b9b3345..3f3be6eb71d 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php @@ -23,7 +23,7 @@ use Magento\Vault\Test\Constraint\AssertCreditCardNotPresentOnCheckout; * 6. Go to One page Checkout * 7. Perform assertions. * - * @group Vault_(CS) + * @group Vault * @ZephyrId MAGETWO-54059, MAGETWO-54072, MAGETWO-54068, MAGETWO-54015, MAGETWO-54011 */ class DeleteSavedCreditCardTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php index 6795c595adc..c3b82af6949 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/ReorderUsingVaultTest.php @@ -28,7 +28,7 @@ use Magento\Mtf\TestCase\Scenario; * 10. Select any available payment token. * 11. Place order. * - * @group Order_Management_(CS) + * @group Order_Management * @ZephyrId MAGETWO-54870, MAGETWO-54872 */ class ReorderUsingVaultTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php index 7ea8aa311fd..902ccc62af7 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/UseVaultOnCheckoutTest.php @@ -31,7 +31,7 @@ use Magento\Mtf\TestCase\Scenario; * 12. Click Place Order button. * 13. Perform assertions. * - * @group One_Page_Checkout_(CS) + * @group One_Page_Checkout * @ZephyrId MAGETWO-46530 */ class UseVaultOnCheckoutTest extends Scenario diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php index d214913fe6d..e430afbbad1 100644 --- a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php +++ b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.php @@ -41,7 +41,7 @@ use Magento\Mtf\TestCase\Injectable; * 9. Go to frontend and login with customer * 10. Perform all assertions. * - * @group Tax_(CS) + * @group Tax * @ZephyrId MAGETWO-29551 */ class CreateTaxWithFptTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php index 71d341acf32..ebe25ca93a9 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php @@ -18,7 +18,7 @@ use Magento\Widget\Test\Fixture\Widget; * 6. Fill widget data according dataset. * 7. Perform all assertions. * - * @group Widget_(PS) + * @group Widget * @ZephyrId MAGETWO-27916 */ class CreateWidgetEntityTest extends AbstractCreateWidgetEntityTest diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php index 4a45f8514f0..ba89d591e36 100644 --- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php @@ -22,7 +22,7 @@ use Magento\Mtf\TestCase\Injectable; * 4. Delete. * 5. Perform all asserts. * - * @group Widget_(PS) + * @group Widget * @ZephyrId MAGETWO-28459 */ class DeleteWidgetEntityTest extends Injectable diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php index 0c072ba9130..9959796828d 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php @@ -21,7 +21,7 @@ use Magento\Customer\Test\Fixture\Customer; * 3. Add created product to Wishlist according to dataset * 4. Perform all assertions * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-29045 */ class AddProductToWishlistEntityTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php index a8ab45a4764..cf16a045c34 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductsToCartFromCustomerWishlistOnFrontendTest.php @@ -21,7 +21,7 @@ use Magento\Customer\Test\Fixture\Customer; * 3. Click "Add to Cart" * 4. Perform asserts * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-25268 */ class AddProductsToCartFromCustomerWishlistOnFrontendTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php index 710580ad811..21841a70b35 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php @@ -26,7 +26,7 @@ use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; * 7. Click Ok * 8. Perform assertions * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-29257 */ class ConfigureProductInCustomerWishlistOnBackendTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php index 1d227e86451..3738dd0631e 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnFrontendTest.php @@ -22,7 +22,7 @@ use Magento\Customer\Test\Fixture\Customer; * 4. Click 'Ok' * 5. Perform assertions * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-29507 */ class ConfigureProductInCustomerWishlistOnFrontendTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php index a043e2669e4..aca814aebca 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductFromCustomerWishlistOnBackendTest.php @@ -27,7 +27,7 @@ use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; * 5. Click 'Delete' * 6. Perform assertions * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-27813 */ class DeleteProductFromCustomerWishlistOnBackendTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php index 9dd4ee579b3..361e80ea56b 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/DeleteProductsFromWishlistOnFrontendTest.php @@ -20,7 +20,7 @@ use Magento\Customer\Test\Fixture\Customer; * 4. Click "Remove item". * 5. Perform all assertions. * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-28874 */ class DeleteProductsFromWishlistOnFrontendTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php index a9dca80c478..7ff599cf43d 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/MoveProductFromShoppingCartToWishlistTest.php @@ -21,7 +21,7 @@ use Magento\Mtf\Fixture\FixtureInterface; * 2. Click 'Move to Wishlist' button from Shopping Cart for added product. * 3. Perform asserts. * - * @group Shopping_Cart_(CS) + * @group Shopping_Cart * @ZephyrId MAGETWO-29545 */ class MoveProductFromShoppingCartToWishlistTest extends AbstractWishlistTest diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php index 30f18cdd8a8..866b60f3dc2 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ShareWishlistEntityTest.php @@ -26,7 +26,7 @@ use Magento\Mtf\TestCase\Injectable; * 5. Click "Share Wishlist" button. * 6. Perform all assertions. * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-23394 * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php index 5ff9f3871e4..06b0bfa77bf 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php @@ -25,7 +25,7 @@ use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; * 4. Open wish list tab. * 5. Perform assertions. * - * @group Wishlist_(CS) + * @group Wishlist * @ZephyrId MAGETWO-29616 */ class ViewProductInCustomerWishlistOnBackendTest extends AbstractWishlistTest diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_mx_category.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/category.xml similarity index 100% rename from dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_mx_category.xml rename to dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/category.xml diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_cs.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_cs.xml deleted file mode 100644 index cdb06f36d53..00000000000 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_cs.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/mtf/Magento/Mtf/TestRunner/etc/testRunner.xsd"> - <rule scope="testcase"> - <allow> - <tag group="domain" value="CS" /> - </allow> - <deny> - <tag group="stable" value="no" /> - <tag group="to_maintain" value="yes" /> - <tag group="test_type" value="3rd_party_test_deprecated" /> - </deny> - </rule> - <rule scope="variation"> - <deny> - <tag group="stable" value="no" /> - <tag group="to_maintain" value="yes" /> - <tag group="test_type" value="3rd_party_test" /> - </deny> - </rule> -</config> diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_mx.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_mx.xml deleted file mode 100644 index 9c5788733cd..00000000000 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_mx.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/mtf/Magento/Mtf/TestRunner/etc/testRunner.xsd"> - <rule scope="testcase"> - <allow> - <tag group="domain" value="MX" /> - </allow> - <deny> - <tag group="test_type" value="3rd_party_test_deprecated" /> - </deny> - </rule> - <rule scope="variation"> - <deny> - <tag group="test_type" value="3rd_party_test" /> - </deny> - </rule> -</config> diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_ps.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_ps.xml deleted file mode 100644 index 9b7e2908593..00000000000 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/domain_ps.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/mtf/Magento/Mtf/TestRunner/etc/testRunner.xsd"> - <rule scope="testcase"> - <allow> - <tag group="domain" value="PS" /> - </allow> - <deny> - <tag group="stable" value="no" /> - <tag group="to_maintain" value="yes" /> - <tag group="test_type" value="3rd_party_test_deprecated" /> - </deny> - </rule> - <rule scope="variation"> - <deny> - <tag group="stable" value="no" /> - <tag group="to_maintain" value="yes" /> - <tag group="test_type" value="3rd_party_test" /> - </deny> - </rule> -</config> -- GitLab From 82015792aa0a7f02b67accde37059ebefb29b826 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Thu, 11 Aug 2016 11:44:26 +0300 Subject: [PATCH 269/838] MAGETWO-56488: Introduce and implement ShipmentTrackCreationInterface --- .../Data/ShipmentTrackCreationInterface.php | 137 +++++++++++++ .../Sales/Api/Data/ShipmentTrackInterface.php | 107 +--------- .../Magento/Sales/Api/Data/TrackInterface.php | 120 +++++++++++ .../Model/Order/Shipment/TrackCreation.php | 189 ++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 1 + 5 files changed, 448 insertions(+), 106 deletions(-) create mode 100644 app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php create mode 100644 app/code/Magento/Sales/Api/Data/TrackInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php new file mode 100644 index 00000000000..dcca11da20d --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php @@ -0,0 +1,137 @@ +<?php + +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Data; + +/** + * Shipment Track Creation interface. + * + * @api + */ +interface ShipmentTrackCreationInterface extends TrackInterface +{ + /** + * Sets the weight for the shipment package. + * + * @param float $weight + * @return $this + */ + public function setWeight($weight); + + /** + * Gets the weight for the shipment package. + * + * @return float Weight. + */ + public function getWeight(); + + /** + * Sets the quantity for the shipment package. + * + * @param float $qty + * @return $this + */ + public function setQty($qty); + + /** + * Gets the quantity for the shipment package. + * + * @return float Quantity. + */ + public function getQty(); + + /** + * Sets the order_id for the shipment package. + * + * @param int $id + * @return $this + */ + public function setOrderId($id); + + /** + * Gets the order_id for the shipment package. + * + * @return int + */ + public function getOrderId(); + + /** + * Sets the track number for the shipment package. + * + * @param string $trackNumber + * @return $this + */ + public function setTrackNumber($trackNumber); + + /** + * Gets the track number for the shipment package. + * + * @return string Track number. + */ + public function getTrackNumber(); + + /** + * Sets the description for the shipment package. + * + * @param string $description + * @return $this + */ + public function setDescription($description); + + /** + * Gets the description for the shipment package. + * + * @return string Description. + */ + public function getDescription(); + + /** + * Sets the title for the shipment package. + * + * @param string $title + * @return $this + */ + public function setTitle($title); + + /** + * Gets the title for the shipment package. + * + * @return string Title. + */ + public function getTitle(); + + /** + * Sets the carrier code for the shipment package. + * + * @param string $code + * @return $this + */ + public function setCarrierCode($code); + + /** + * Gets the carrier code for the shipment package. + * + * @return string Carrier code. + */ + public function getCarrierCode(); + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php index f28a0b0e7a1..e641d285bc5 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php @@ -13,7 +13,7 @@ namespace Magento\Sales\Api\Data; * shipments. * @api */ -interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataInterface +interface ShipmentTrackInterface extends TrackInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. @@ -63,13 +63,6 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn */ const UPDATED_AT = 'updated_at'; - /** - * Gets the carrier code for the shipment package. - * - * @return string Carrier code. - */ - public function getCarrierCode(); - /** * Gets the created-at timestamp for the shipment package. * @@ -85,13 +78,6 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn */ public function setCreatedAt($createdAt); - /** - * Gets the description for the shipment package. - * - * @return string Description. - */ - public function getDescription(); - /** * Gets the ID for the shipment package. * @@ -107,13 +93,6 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn */ public function setEntityId($entityId); - /** - * Gets the order_id for the shipment package. - * - * @return int - */ - public function getOrderId(); - /** * Gets the parent ID for the shipment package. * @@ -121,27 +100,6 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn */ public function getParentId(); - /** - * Gets the quantity for the shipment package. - * - * @return float Quantity. - */ - public function getQty(); - - /** - * Gets the title for the shipment package. - * - * @return string Title. - */ - public function getTitle(); - - /** - * Gets the track number for the shipment package. - * - * @return string Track number. - */ - public function getTrackNumber(); - /** * Gets the updated-at timestamp for the shipment package. * @@ -149,13 +107,6 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn */ public function getUpdatedAt(); - /** - * Gets the weight for the shipment package. - * - * @return float Weight. - */ - public function getWeight(); - /** * Sets the updated-at timestamp for the shipment package. * @@ -172,62 +123,6 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn */ public function setParentId($id); - /** - * Sets the weight for the shipment package. - * - * @param float $weight - * @return $this - */ - public function setWeight($weight); - - /** - * Sets the quantity for the shipment package. - * - * @param float $qty - * @return $this - */ - public function setQty($qty); - - /** - * Sets the order_id for the shipment package. - * - * @param int $id - * @return $this - */ - public function setOrderId($id); - - /** - * Sets the track number for the shipment package. - * - * @param string $trackNumber - * @return $this - */ - public function setTrackNumber($trackNumber); - - /** - * Sets the description for the shipment package. - * - * @param string $description - * @return $this - */ - public function setDescription($description); - - /** - * Sets the title for the shipment package. - * - * @param string $title - * @return $this - */ - public function setTitle($title); - - /** - * Sets the carrier code for the shipment package. - * - * @param string $code - * @return $this - */ - public function setCarrierCode($code); - /** * Retrieve existing extension attributes object or create a new one. * diff --git a/app/code/Magento/Sales/Api/Data/TrackInterface.php b/app/code/Magento/Sales/Api/Data/TrackInterface.php new file mode 100644 index 00000000000..5b48aee85b3 --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/TrackInterface.php @@ -0,0 +1,120 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Api\Data; + +/** + * Shipment Track Creation interface. + * + * @api + */ +interface TrackInterface extends \Magento\Framework\Api\ExtensibleDataInterface +{ + /** + * Sets the weight for the shipment package. + * + * @param float $weight + * @return $this + */ + public function setWeight($weight); + + /** + * Gets the weight for the shipment package. + * + * @return float Weight. + */ + public function getWeight(); + + /** + * Sets the quantity for the shipment package. + * + * @param float $qty + * @return $this + */ + public function setQty($qty); + + /** + * Gets the quantity for the shipment package. + * + * @return float Quantity. + */ + public function getQty(); + + /** + * Sets the order_id for the shipment package. + * + * @param int $id + * @return $this + */ + public function setOrderId($id); + + /** + * Gets the order_id for the shipment package. + * + * @return int + */ + public function getOrderId(); + + /** + * Sets the track number for the shipment package. + * + * @param string $trackNumber + * @return $this + */ + public function setTrackNumber($trackNumber); + + /** + * Gets the track number for the shipment package. + * + * @return string Track number. + */ + public function getTrackNumber(); + + /** + * Sets the description for the shipment package. + * + * @param string $description + * @return $this + */ + public function setDescription($description); + + /** + * Gets the description for the shipment package. + * + * @return string Description. + */ + public function getDescription(); + + /** + * Sets the title for the shipment package. + * + * @param string $title + * @return $this + */ + public function setTitle($title); + + /** + * Gets the title for the shipment package. + * + * @return string Title. + */ + public function getTitle(); + + /** + * Sets the carrier code for the shipment package. + * + * @param string $code + * @return $this + */ + public function setCarrierCode($code); + + /** + * Gets the carrier code for the shipment package. + * + * @return string Carrier code. + */ + public function getCarrierCode(); +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php new file mode 100644 index 00000000000..4774ada6a5a --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -0,0 +1,189 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; + +/** + * Class TrackCreation + */ +class TrackCreation implements ShipmentTrackCreationInterface +{ + /** + * @var float + */ + private $weight; + + /** + * @var float + */ + private $qty; + + /** + * @var int + */ + private $orderId; + + /** + * @var string + */ + private $trackNumber; + + /** + * @var string + */ + private $description; + + /** + * @var string + */ + private $title; + + /** + * @var string + */ + private $carrierCode; + + /** + * @var \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface + */ + private $extensionAttributes; + + /** + * {@inheritdoc} + */ + public function getWeight() + { + return $this->weight; + } + + /** + * {@inheritdoc} + */ + public function setWeight($weight) + { + $this->weight = $weight; + } + + /** + * {@inheritdoc} + */ + public function getQty() + { + return $this->qty; + } + + /** + * {@inheritdoc} + */ + public function setQty($qty) + { + $this->qty = $qty; + } + + /** + * {@inheritdoc} + */ + public function getOrderId() + { + return $this->orderId; + } + + /** + * {@inheritdoc} + */ + public function setOrderId($orderId) + { + $this->orderId = $orderId; + } + + /** + * {@inheritdoc} + */ + public function getTrackNumber() + { + return $this->trackNumber; + } + + /** + * {@inheritdoc} + */ + public function setTrackNumber($trackNumber) + { + $this->trackNumber = $trackNumber; + } + + /** + * {@inheritdoc} + */ + public function getDescription() + { + return $this->description; + } + + /** + * {@inheritdoc} + */ + public function setDescription($description) + { + $this->description = $description; + } + + /** + * {@inheritdoc} + */ + public function getTitle() + { + return $this->title; + } + + /** + * {@inheritdoc} + */ + public function setTitle($title) + { + $this->title = $title; + } + + /** + * {@inheritdoc} + */ + public function getCarrierCode() + { + return $this->carrierCode; + } + + /** + * {@inheritdoc} + */ + public function setCarrierCode($carrierCode) + { + $this->carrierCode = $carrierCode; + } + + /** + * {@inheritdoc} + * + * @return \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface|null + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * {@inheritdoc} + * + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes) + { + $this->extensionAttributes = $extensionAttributes; + return $this; + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 89594620b09..22e982a6b2c 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -93,6 +93,7 @@ <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> <preference for="Magento\Sales\Api\OrderInvoiceInterface" type="Magento\Sales\Model\OrderInvoice"/> <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> + <preference for="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" type="Magento\Sales\Model\Order\Shipment\TrackCreation"/> <type name="Magento\Sales\Model\ResourceModel\Report" shared="false"/> <type name="Magento\Sales\Model\Order\Pdf\Config\Reader"> <arguments> -- GitLab From 691d670c1b6ba21987bc7540fb3d29c02fdc2828 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 11:47:42 +0300 Subject: [PATCH 270/838] MAGETWO-56012: SearchCriteria Unified Processing --- app/code/Magento/Catalog/Model/CategoryList.php | 3 +-- app/code/Magento/Catalog/Model/ProductRepository.php | 2 +- app/code/Magento/Catalog/etc/di.xml | 6 +++--- .../Customer/Model/ResourceModel/CustomerRepository.php | 2 +- .../Customer/Model/ResourceModel/GroupRepository.php | 2 +- app/code/Magento/Customer/etc/di.xml | 8 ++++---- app/etc/di.xml | 4 ++-- ...tionProcessorComposite.php => CollectionProcessor.php} | 2 +- .../SearchCriteria/CollectionProcessorCompositeTest.php | 8 ++++---- 9 files changed, 18 insertions(+), 19 deletions(-) rename lib/internal/Magento/Framework/Api/SearchCriteria/{CollectionProcessorComposite.php => CollectionProcessor.php} (93%) diff --git a/app/code/Magento/Catalog/Model/CategoryList.php b/app/code/Magento/Catalog/Model/CategoryList.php index fd457f6b311..7e701123e99 100644 --- a/app/code/Magento/Catalog/Model/CategoryList.php +++ b/app/code/Magento/Catalog/Model/CategoryList.php @@ -12,7 +12,6 @@ use Magento\Catalog\Api\Data\CategorySearchResultsInterfaceFactory; use Magento\Catalog\Model\ResourceModel\Category\Collection; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; -use Magento\Framework\Api\Search\FilterGroup; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; @@ -98,7 +97,7 @@ class CategoryList implements CategoryListInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite' + 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php index 146668c9d63..ad8c45596e1 100644 --- a/app/code/Magento/Catalog/Model/ProductRepository.php +++ b/app/code/Magento/Catalog/Model/ProductRepository.php @@ -685,7 +685,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite' + 'Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 70a1b8375fb..36f072d3b0a 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -812,7 +812,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor</item> @@ -823,12 +823,12 @@ </virtualType> <type name="Magento\Catalog\Model\ProductRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Catalog\Model\Api\SearchCriteria\ProductCollectionProcessor</argument> </arguments> </type> <type name="\Magento\Catalog\Model\CategoryList"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor</argument> </arguments> </type> </config> diff --git a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php index c76d06206ac..16896063709 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php @@ -363,7 +363,7 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite' + 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php b/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php index e4d780d4e82..044616f141c 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/GroupRepository.php @@ -344,7 +344,7 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite' + 'Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index bb384d7f282..d8f320161ab 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -317,7 +317,7 @@ </type> <type name="Magento\Customer\Model\ResourceModel\CustomerRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor</argument> </arguments> </type> <virtualType name="Magento\Customer\Model\Api\SearchCriteria\CollectionProcessor\GroupFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> @@ -341,7 +341,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\CollectionProcessor\GroupFilterProcessor</item> @@ -352,12 +352,12 @@ </virtualType> <type name="Magento\Customer\Model\ResourceModel\GroupRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Customer\Model\Api\SearchCriteria\GroupCollectionProcessor</argument> </arguments> </type> <type name="Magento\Customer\Model\ResourceModel\AddressRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor</argument> </arguments> </type> </config> diff --git a/app/etc/di.xml b/app/etc/di.xml index a536794401b..28f0d024c3a 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1209,8 +1209,8 @@ </argument> </arguments> </type> - <preference for="Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite" /> - <type name="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <preference for="Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor" /> + <type name="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor.php similarity index 93% rename from lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php rename to lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor.php index d4f0229877e..e4769769a97 100644 --- a/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessorComposite.php +++ b/lib/internal/Magento/Framework/Api/SearchCriteria/CollectionProcessor.php @@ -8,7 +8,7 @@ namespace Magento\Framework\Api\SearchCriteria; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Data\Collection\AbstractDb; -class CollectionProcessorComposite implements CollectionProcessorInterface +class CollectionProcessor implements CollectionProcessorInterface { /** * @var CollectionProcessorInterface[] diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php index 5cbcb071664..ae52d722e05 100644 --- a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php +++ b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php @@ -5,22 +5,22 @@ */ namespace Magento\Framework\Api\Test\Unit\SearchCriteria; -use Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Data\Collection\AbstractDb; -class CollectionProcessorCompositeTest extends \PHPUnit_Framework_TestCase +class CollectionProcessorTest extends \PHPUnit_Framework_TestCase { /** * Return model * * @param CollectionProcessorInterface[] $processors - * @return CollectionProcessorComposite + * @return CollectionProcessor */ private function getModel(array $processors) { - return new CollectionProcessorComposite($processors); + return new CollectionProcessor($processors); } public function testProcess() -- GitLab From 3f66a6fd5dd3761e0ffa36e675f4744f4bd66720 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 11:49:22 +0300 Subject: [PATCH 271/838] MAGETWO-56079: SearchCriteria Unified Processing for Cms, Customer and Eav modules --- app/code/Magento/Cms/Model/BlockRepository.php | 2 +- app/code/Magento/Cms/Model/PageRepository.php | 2 +- app/code/Magento/Cms/etc/di.xml | 8 ++++---- .../Model/ResourceModel/AddressRepository.php | 2 +- .../Magento/Eav/Model/Attribute/GroupRepository.php | 2 +- app/code/Magento/Eav/Model/AttributeRepository.php | 5 ++--- .../Magento/Eav/Model/AttributeSetRepository.php | 2 +- app/code/Magento/Eav/etc/di.xml | 12 ++++++------ 8 files changed, 17 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Cms/Model/BlockRepository.php b/app/code/Magento/Cms/Model/BlockRepository.php index 59e84c476d0..5719316dc36 100644 --- a/app/code/Magento/Cms/Model/BlockRepository.php +++ b/app/code/Magento/Cms/Model/BlockRepository.php @@ -215,7 +215,7 @@ class BlockRepository implements BlockRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessorComposite' + 'Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Cms/Model/PageRepository.php b/app/code/Magento/Cms/Model/PageRepository.php index 76f0de8dd86..9ab3b03d4ae 100644 --- a/app/code/Magento/Cms/Model/PageRepository.php +++ b/app/code/Magento/Cms/Model/PageRepository.php @@ -223,7 +223,7 @@ class PageRepository implements PageRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessorComposite' + 'Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Cms/etc/di.xml b/app/code/Magento/Cms/etc/di.xml index a49136c2f1f..cae674b4a0d 100644 --- a/app/code/Magento/Cms/etc/di.xml +++ b/app/code/Magento/Cms/etc/di.xml @@ -153,7 +153,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\PageFilterProcessor</item> @@ -164,7 +164,7 @@ </virtualType> <type name="Magento\Cms\Model\PageRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\PageCollectionProcessor</argument> </arguments> </type> <virtualType name="Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\BlockFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> @@ -174,7 +174,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\CollectionProcessor\BlockFilterProcessor</item> @@ -185,7 +185,7 @@ </virtualType> <type name="Magento\Cms\Model\BlockRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Cms\Model\Api\SearchCriteria\BlockCollectionProcessor</argument> </arguments> </type> </config> diff --git a/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php b/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php index eb477d6b311..67d4ea32369 100644 --- a/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php +++ b/app/code/Magento/Customer/Model/ResourceModel/AddressRepository.php @@ -329,7 +329,7 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite' + 'Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php index da3426d6cf3..20315edfbe8 100644 --- a/app/code/Magento/Eav/Model/Attribute/GroupRepository.php +++ b/app/code/Magento/Eav/Model/Attribute/GroupRepository.php @@ -212,7 +212,7 @@ class GroupRepository implements \Magento\Eav\Api\AttributeGroupRepositoryInterf { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessorComposite' + 'Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Eav/Model/AttributeRepository.php b/app/code/Magento/Eav/Model/AttributeRepository.php index 0894db43bb7..1b3e1cb76d1 100644 --- a/app/code/Magento/Eav/Model/AttributeRepository.php +++ b/app/code/Magento/Eav/Model/AttributeRepository.php @@ -5,8 +5,7 @@ */ namespace Magento\Eav\Model; -use Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection; -use Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; @@ -201,7 +200,7 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - CollectionProcessorComposite::class + CollectionProcessor::class ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Eav/Model/AttributeSetRepository.php b/app/code/Magento/Eav/Model/AttributeSetRepository.php index 4a5e239f6f1..f1c71373840 100644 --- a/app/code/Magento/Eav/Model/AttributeSetRepository.php +++ b/app/code/Magento/Eav/Model/AttributeSetRepository.php @@ -184,7 +184,7 @@ class AttributeSetRepository implements AttributeSetRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - 'Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessorComposite' + 'Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index 774fdb99622..49d6753bc48 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -82,7 +82,7 @@ <type name="Magento\Eav\Model\Entity\AbstractEntity"> <plugin name="clean_cache" type="Magento\Framework\App\Cache\FlushCacheByTags" /> </type> - <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor</item> @@ -93,7 +93,7 @@ </virtualType> <type name="Magento\Eav\Model\AttributeRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Framework\Api\SearchCriteria\CollectionProcessor</argument> </arguments> </type> <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeSetFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> @@ -103,7 +103,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeSetFilterProcessor</item> @@ -114,7 +114,7 @@ </virtualType> <type name="Magento\Eav\Model\AttributeSetRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeSetCollectionProcessor</argument> </arguments> </type> <virtualType name="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupFilterProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> @@ -138,7 +138,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\AttributeGroupFilterProcessor</item> @@ -149,7 +149,7 @@ </virtualType> <type name="Magento\Eav\Model\Attribute\GroupRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessor</argument> </arguments> </type> </config> -- GitLab From 39c9b6201536d0abba018cbd435a6f1ae7ccfa77 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 11:50:44 +0300 Subject: [PATCH 272/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Quote/Model/QuoteRepository.php | 2 +- app/code/Magento/Tax/Model/Calculation/RateRepository.php | 2 +- app/code/Magento/Tax/Model/TaxClass/Repository.php | 2 +- app/code/Magento/Tax/Model/TaxRuleRepository.php | 2 +- app/code/Magento/Tax/etc/di.xml | 8 ++++---- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteRepository.php b/app/code/Magento/Quote/Model/QuoteRepository.php index 34dad6f0fd0..c73b7715d77 100644 --- a/app/code/Magento/Quote/Model/QuoteRepository.php +++ b/app/code/Magento/Quote/Model/QuoteRepository.php @@ -299,7 +299,7 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + \Magento\Framework\Api\SearchCriteria\CollectionProcessor::class ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index 3ccf822e865..34b746a7c0f 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -310,7 +310,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - '\Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessorComposite' + '\Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/Model/TaxClass/Repository.php b/app/code/Magento/Tax/Model/TaxClass/Repository.php index 3ee54ae8aaa..2eb8b1757f4 100644 --- a/app/code/Magento/Tax/Model/TaxClass/Repository.php +++ b/app/code/Magento/Tax/Model/TaxClass/Repository.php @@ -246,7 +246,7 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - \Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite::class + \Magento\Framework\Api\SearchCriteria\CollectionProcessor::class ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php index 5fdb2483b3e..9d18ff01767 100644 --- a/app/code/Magento/Tax/Model/TaxRuleRepository.php +++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php @@ -227,7 +227,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - '\Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessorComposite' + '\Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 28d47ca7c6f..a626c5525e9 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -87,15 +87,15 @@ </type> <type name="Magento\Tax\Model\TaxRuleRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessor</argument> </arguments> </type> <type name="Magento\Tax\Model\Calculation\RateRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessorComposite</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessor</argument> </arguments> </type> - <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRateFilterProcessor</item> @@ -158,7 +158,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessorComposite" type="Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite"> + <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="joins" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleJoinProcessor</item> -- GitLab From 9e440a0b3fc88232a6a18a34cca12e9c500c421e Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 11:51:47 +0300 Subject: [PATCH 273/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui --- .../Magento/Ui/Model/ResourceModel/BookmarkRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php index 16776369667..7b5c77933ae 100644 --- a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php +++ b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php @@ -5,7 +5,7 @@ */ namespace Magento\Ui\Model\ResourceModel; -use Magento\Framework\Api\SearchCriteria\CollectionProcessorComposite; +use Magento\Framework\Api\SearchCriteria\CollectionProcessor; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SortOrder; @@ -181,7 +181,7 @@ class BookmarkRepository implements BookmarkRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - CollectionProcessorComposite::class + CollectionProcessor::class ); } return $this->collectionProcessor; -- GitLab From 206ce051fc5bd029192a05a5495aa74bc65a5ef5 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 11 Aug 2016 12:09:11 +0300 Subject: [PATCH 274/838] MAGETWO-51616: Admin data grids search values aren't trimmed --- .../Magento/Ui/view/base/web/js/grid/filters/filters.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index 0ce86c5fad8..24e502549ac 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -31,7 +31,11 @@ define([ * @returns {Object} */ function removeEmpty(data) { - return utils.mapRecursive(data, utils.removeEmptyValues.bind(utils)); + var result = utils.mapRecursive(data, utils.removeEmptyValues.bind(utils)); + + return utils.mapRecursive(result, function (value) { + return _.isString(value) ? value.trim() : value; + }); } return Collection.extend({ -- GitLab From 0f52f1a7e2c27dca757cff1fa8462327834fa7e7 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 12:20:59 +0300 Subject: [PATCH 275/838] MAGETWO-56012: SearchCriteria Unified Processing --- ...tionProcessorCompositeTest.php => CollectionProcessorTest.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/{CollectionProcessorCompositeTest.php => CollectionProcessorTest.php} (100%) diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorTest.php similarity index 100% rename from lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorCompositeTest.php rename to lib/internal/Magento/Framework/Api/Test/Unit/SearchCriteria/CollectionProcessorTest.php -- GitLab From aaec6caaa716f974d792ac1442e3daac12123d39 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 12:21:12 +0300 Subject: [PATCH 276/838] MAGETWO-56079: SearchCriteria Unified Processing for Cms, Customer and Eav modules --- .../Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php b/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php index e6d9ce9de9e..d90363e40bf 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/AttributeRepositoryTest.php @@ -110,6 +110,9 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase $this->model->getList(null, $searchCriteriaMock); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testGetList() { $entityTypeCode = 'entity_type_code'; -- GitLab From e6f320986aa3adafe2cc792dbe5f60cf47cc29fe Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 11 Aug 2016 12:30:07 +0300 Subject: [PATCH 277/838] MAGETWO-56743: Unable to upgrade with split databases --- .../OfflineShipping/Setup/InstallSchema.php | 26 +++++++++----- .../Magento/Paypal/Setup/InstallSchema.php | 1 + .../Persistent/Setup/InstallSchema.php | 9 +++-- .../SalesSequence/Setup/InstallSchema.php | 34 +++++++++++++------ .../Magento/Vault/Setup/InstallSchema.php | 1 + 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/OfflineShipping/Setup/InstallSchema.php b/app/code/Magento/OfflineShipping/Setup/InstallSchema.php index 8ce77e6098b..0c2b62f9088 100644 --- a/app/code/Magento/OfflineShipping/Setup/InstallSchema.php +++ b/app/code/Magento/OfflineShipping/Setup/InstallSchema.php @@ -15,6 +15,16 @@ use Magento\Framework\Setup\SchemaSetupInterface; */ class InstallSchema implements InstallSchemaInterface { + /** + * @var string + */ + private static $quoteConnectionName = 'checkout'; + + /** + * @var string + */ + private static $salesConnectionName = 'sales'; + /** * {@inheritdoc} * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -105,32 +115,32 @@ class InstallSchema implements InstallSchemaInterface ['unsigned' => true, 'nullable' => false, 'default' => '0'], 'Simple Free Shipping' ); - $installer->getConnection()->addColumn( - $installer->getTable('sales_order_item'), + $installer->getConnection(self::$salesConnectionName)->addColumn( + $installer->getTable('sales_order_item', self::$salesConnectionName), 'free_shipping', \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, null, ['unsigned' => true, 'nullable' => false, 'default' => '0'], 'Free Shipping' ); - $installer->getConnection()->addColumn( - $installer->getTable('quote_address'), + $installer->getConnection(self::$quoteConnectionName)->addColumn( + $installer->getTable('quote_address', self::$quoteConnectionName), 'free_shipping', \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, null, ['unsigned' => true, 'nullable' => false, 'default' => '0'], 'Free Shipping' ); - $installer->getConnection()->addColumn( - $installer->getTable('quote_item'), + $installer->getConnection(self::$quoteConnectionName)->addColumn( + $installer->getTable('quote_item', self::$quoteConnectionName), 'free_shipping', \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, null, ['unsigned' => true, 'nullable' => false, 'default' => '0'], 'Free Shipping' ); - $installer->getConnection()->addColumn( - $installer->getTable('quote_address_item'), + $installer->getConnection(self::$quoteConnectionName)->addColumn( + $installer->getTable('quote_address_item', self::$quoteConnectionName), 'free_shipping', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, diff --git a/app/code/Magento/Paypal/Setup/InstallSchema.php b/app/code/Magento/Paypal/Setup/InstallSchema.php index d0a07242ad7..517a3dcbb83 100644 --- a/app/code/Magento/Paypal/Setup/InstallSchema.php +++ b/app/code/Magento/Paypal/Setup/InstallSchema.php @@ -142,6 +142,7 @@ class InstallSchema implements InstallSchemaInterface 'agreement_id', \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE )->addForeignKey( + // TODO: refactor without FK. $installer->getFkName('paypal_billing_agreement_order', 'order_id', 'sales_order', 'entity_id'), 'order_id', $installer->getTable('sales_order'), diff --git a/app/code/Magento/Persistent/Setup/InstallSchema.php b/app/code/Magento/Persistent/Setup/InstallSchema.php index 940133fcf5d..89e7d88fbd0 100644 --- a/app/code/Magento/Persistent/Setup/InstallSchema.php +++ b/app/code/Magento/Persistent/Setup/InstallSchema.php @@ -15,6 +15,11 @@ use Magento\Framework\Setup\SchemaSetupInterface; */ class InstallSchema implements InstallSchemaInterface { + /** + * @var string + */ + private static $connectionName = 'checkout'; + /** * {@inheritdoc} */ @@ -97,8 +102,8 @@ class InstallSchema implements InstallSchemaInterface * Alter quote table with is_persistent flag * */ - $installer->getConnection()->addColumn( - $installer->getTable('quote'), + $installer->getConnection(self::$connectionName)->addColumn( + $installer->getTable('quote', self::$connectionName), 'is_persistent', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, diff --git a/app/code/Magento/SalesSequence/Setup/InstallSchema.php b/app/code/Magento/SalesSequence/Setup/InstallSchema.php index 023094527c5..10ac971eb2c 100644 --- a/app/code/Magento/SalesSequence/Setup/InstallSchema.php +++ b/app/code/Magento/SalesSequence/Setup/InstallSchema.php @@ -14,6 +14,11 @@ use Magento\Framework\Setup\SchemaSetupInterface; */ class InstallSchema implements InstallSchemaInterface { + /** + * @var string + */ + private static $connectionName = 'sales'; + /** * {@inheritdoc} * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -25,8 +30,8 @@ class InstallSchema implements InstallSchemaInterface /** * Create table 'sales_sequence_profile' */ - $table = $installer->getConnection()->newTable( - $installer->getTable('sales_sequence_profile') + $table = $installer->getConnection(self::$connectionName)->newTable( + $installer->getTable('sales_sequence_profile', self::$connectionName) )->addColumn( 'profile_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, @@ -84,24 +89,31 @@ class InstallSchema implements InstallSchemaInterface $installer->getIdxName( 'sales_sequence_profile', ['meta_id', 'prefix', 'suffix'], - \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE, + '', + self::$connectionName ), ['meta_id', 'prefix', 'suffix'], ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] )->addForeignKey( - $installer->getFkName('sales_sequence_profile', 'meta_id', 'sales_sequence_meta', 'meta_id'), + $installer->getFkName( + 'sales_sequence_profile', + 'meta_id', + 'sales_sequence_meta', + 'meta_id', self::$connectionName + ), 'meta_id', - $installer->getTable('sales_sequence_meta'), + $installer->getTable('sales_sequence_meta', self::$connectionName), 'meta_id', \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE ); - $installer->getConnection()->createTable($table); + $installer->getConnection(self::$connectionName)->createTable($table); /** * Create table 'sales_sequence_meta' */ - $table = $installer->getConnection()->newTable( - $installer->getTable('sales_sequence_meta') + $table = $installer->getConnection(self::$connectionName)->newTable( + $installer->getTable('sales_sequence_meta', self::$connectionName) )->addColumn( 'meta_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, @@ -130,12 +142,14 @@ class InstallSchema implements InstallSchemaInterface $installer->getIdxName( 'sales_sequence_meta', ['entity_type', 'store_id'], - \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE + \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE, + '', + self::$connectionName ), ['entity_type', 'store_id'], ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE] ); - $installer->getConnection()->createTable($table); + $installer->getConnection(self::$connectionName)->createTable($table); $installer->endSetup(); } } diff --git a/app/code/Magento/Vault/Setup/InstallSchema.php b/app/code/Magento/Vault/Setup/InstallSchema.php index 6f505d130e4..1990f5d4a0c 100644 --- a/app/code/Magento/Vault/Setup/InstallSchema.php +++ b/app/code/Magento/Vault/Setup/InstallSchema.php @@ -145,6 +145,7 @@ class InstallSchema implements InstallSchemaInterface ['unsigned' => true, 'nullable' => false, 'primary' => true], 'Payment token Id' )->addForeignKey( + // TODO: refactor without FK. $setup->getFkName( $setup->getTable(self::ORDER_PAYMENT_TO_PAYMENT_TOKEN_TABLE), 'order_payment_id', -- GitLab From be8e36a71c88a8dc21e656ea974761b77607d174 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 11 Aug 2016 12:48:21 +0300 Subject: [PATCH 278/838] MAGETWO-56572: Introduce and implement ShipmentCommentCreationInterface --- .../Sales/Api/Data/InvoiceCommentCreationInterface.php | 4 +++- .../Magento/Sales/Api/Data/InvoiceCommentInterface.php | 7 +++---- .../Sales/Api/Data/InvoiceItemCreationInterface.php | 4 +++- app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php | 5 ++--- .../Sales/Api/Data/ShipmentCommentCreationInterface.php | 6 +++--- .../Magento/Sales/Api/Data/ShipmentCommentInterface.php | 7 +++---- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php index 34039310778..5e4d85e93cb 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentCreationInterface.php @@ -6,12 +6,14 @@ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Interface InvoiceCommentCreationInterface * * @api */ -interface InvoiceCommentCreationInterface extends \Magento\Sales\Api\Data\CommentInterface +interface InvoiceCommentCreationInterface extends ExtensibleDataInterface, CommentInterface { /** * Retrieve existing extension attributes object or create a new one. diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php index dd9b1a77180..f661a1ab6a4 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php @@ -5,6 +5,8 @@ */ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Invoice comment interface. * @@ -12,10 +14,7 @@ namespace Magento\Sales\Api\Data; * invoice history. * @api */ -interface InvoiceCommentInterface - extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\CommentInterface, - \Magento\Sales\Api\Data\EntityInterface +interface InvoiceCommentInterface extends ExtensibleDataInterface, CommentInterface, EntityInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php index d4b250ed911..2f2ddfbf758 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemCreationInterface.php @@ -6,6 +6,8 @@ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Input argument for invoice creation * @@ -13,7 +15,7 @@ namespace Magento\Sales\Api\Data; * * @api */ -interface InvoiceItemCreationInterface extends LineItemInterface +interface InvoiceItemCreationInterface extends LineItemInterface, ExtensibleDataInterface { /** * Retrieve existing extension attributes object or create a new one. diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php index 0f07bfcad23..811b0ad0653 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php @@ -5,15 +5,14 @@ */ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; /** * Invoice item interface. * * An invoice is a record of the receipt of payment for an order. An invoice item is a purchased item in an invoice. * @api */ -interface InvoiceItemInterface - extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\LineItemInterface +interface InvoiceItemInterface extends ExtensibleDataInterface, LineItemInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php index 0c17af1aae2..40beaa32d02 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentCreationInterface.php @@ -5,13 +5,13 @@ */ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Interface ShipmentCommentCreationInterface * @api */ -interface ShipmentCommentCreationInterface - extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\CommentInterface +interface ShipmentCommentCreationInterface extends ExtensibleDataInterface, CommentInterface { /** * Retrieve existing extension attributes object or create a new one. diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php index 3b17b1b9559..0c00bf80d78 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php @@ -5,6 +5,8 @@ */ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Shipment comment interface. * @@ -12,10 +14,7 @@ namespace Magento\Sales\Api\Data; * document lists the products and their quantities in the delivery package. A shipment document can contain comments. * @api */ -interface ShipmentCommentInterface - extends \Magento\Framework\Api\ExtensibleDataInterface, - \Magento\Sales\Api\Data\CommentInterface, - \Magento\Sales\Api\Data\EntityInterface +interface ShipmentCommentInterface extends ExtensibleDataInterface, CommentInterface, EntityInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. -- GitLab From f8e75a3fb4c370567ab35d212645acf6e3465a06 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 11 Aug 2016 12:57:03 +0300 Subject: [PATCH 279/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../web/app/setup/styles/less/_setup.less | 2 +- .../styles/less/pages/_readiness-check.less | 66 ++++++++++++++ setup/pub/styles/setup.css | 2 +- .../setup/readiness-check/progress.phtml | 87 ++++++++++--------- 4 files changed, 113 insertions(+), 44 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less index 6392ef60be9..23154cdb878 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/_setup.less @@ -98,7 +98,7 @@ // Updater pages //@import '../../../updater/styles/less/pages/_common.less'; //@import '../../../updater/styles/less/pages/_home.less'; -//@import '../../../updater/styles/less/pages/_component-manager.less'; +//@import '../../../updater/styles/less/pages/_extension-manager.less'; //@import '../../../updater/styles/less/pages/_login.less'; // diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less index 6adc7eddae4..e4da9c18d34 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less @@ -66,6 +66,72 @@ margin-top: .3rem; } +.extensions-information { + margin-bottom: 5rem; + + .message:before { + margin-top: 0; + top: 1.8rem; + } + + .message { + margin-bottom: 1rem; + } + + .extensions-container { + padding: 0 2rem; + } + + .list { + margin-bottom: 1rem; + } + + .list select { + cursor: pointer; + } + + .list select:disabled { + cursor: default; + background: #cccccc; + } + + .list { + .abs-action-delete { + font-size: 1.7rem; + padding-top: 0; + } + } +} + +.delete-modal-wrap { + padding: 0 4% @indent__xl; + + .delete-modal-header { + .lib-font-size(34); + font-weight: @font-weight__light; + margin: 0 0 @indent__base; + + span { + display: inline-block; + padding: .9rem 0 0; + vertical-align: top; + } + } + + .form-actions { + display: table; + margin-top: -1.3rem; + + .links { + display: table-header-group; + } + + .actions { + padding: @indent__xl 0 0; + } + } +} + // // Mobile // _____________________________________________ diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css index 4ee5d4979d2..dd962921ad9 100644 --- a/setup/pub/styles/setup.css +++ b/setup/pub/styles/setup.css @@ -3,4 +3,4 @@ * See COPYING.txt for license details. */ -.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-moz-appearance:none;-webkit-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title,.admin__menu .submenu .parent>a{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-extension>a:before{content:'\e612'}.admin__menu .item-component>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file +.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.extensions-information{margin-bottom:5rem}.extensions-information .message:before{margin-top:0;top:1.8rem}.extensions-information .message{margin-bottom:1rem}.extensions-information .extensions-container{padding:0 2rem}.extensions-information .list{margin-bottom:1rem}.extensions-information .list select{cursor:pointer}.extensions-information .list select:disabled{cursor:default;background:#ccc}.extensions-information .list .abs-action-delete{font-size:1.7rem;padding-top:0}.delete-modal-wrap{padding:0 4% 4rem}.delete-modal-wrap .delete-modal-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.delete-modal-wrap .delete-modal-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.delete-modal-wrap .form-actions{display:table;margin-top:-1.3rem}.delete-modal-wrap .form-actions .links{display:table-header-group}.delete-modal-wrap .form-actions .actions{padding:4rem 0 0}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 4634e9efaa4..93f2cfdc04e 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -7,44 +7,7 @@ // @codingStandardsIgnoreFile ?> -<style> - .top-ico:before { - margin-top: 0; - top: 1.8rem; - } - .list select:disabled { - background: #cccccc; - } -</style> -<div class="message top-ico" ng-class="{'message-warning':needReCheck && !checkingInProgress()}" - ng-if="$state.current.type == 'update' && getObjectSize(getExtensionsList()) > 0" -> - <h3>Extensions to {{$state.current.type}}:</h3> - <div style="padding: 0 0 2rem 0;">You can change the version or remove the extension from the updating.</div> - - <ul class="list"> - <li ng-repeat="extension in getExtensionsList()"> - <strong>{{extension.name}} {{getCurrentVersion(extension.name)}}</strong> to - <select ng-change="versionChanged()" - ng-model="extension.version" - ng-disabled="checkingInProgress()" - > - <option ng-repeat="version in getVersionsList(extension.name)" - ng-selected="version == extension.version" - value="{{version}}" - >Version {{version}}</option> - </select> - <button style="padding-top: 0;" class="abs-action-delete" - ng-click="openDialog(extension.name)" - ng-show="!checkingInProgress() && getObjectSize(getExtensionsList()) > 1"></button> - </li> - </ul> - - <div ng-show="needReCheck && !checkingInProgress()"> - <strong>After your changes You need to recheck component dependency. Please click - <a href="#" ng-click="$state.forceReload()">here</a>.</strong> - </div> -</div> + <div ng-switch="isCompleted()"> @@ -74,6 +37,46 @@ </div> +<div class="extensions-information" ng-if="$state.current.type == 'update' && getObjectSize(getExtensionsList()) > 0"> + <div class="message message-warning"> + We found some extensions with available version updates. We recommend that you update to the recommended + versions or remove these extensions from the installation process. We found some extensions with available + version updates. We recommend that you update to the recommended versions or remove these extensions from + the installation process. + </div> + <div class="extensions-container"> + <p><strong>Update these extension(s)</strong></p> + <ul class="list"> + <li ng-repeat="extension in getExtensionsList()"> + {{extension.name}} {{getCurrentVersion(extension.name)}} to + <select ng-change="versionChanged()" + ng-model="extension.version" + ng-disabled="checkingInProgress()" + > + <option ng-repeat="version in getVersionsList(extension.name)" + ng-selected="version == extension.version" + value="{{version}}" + >Version {{version}}</option> + </select> + <button class="abs-action-delete" + ng-click="openDialog(extension.name)" + ng-show="!checkingInProgress() && getObjectSize(getExtensionsList()) > 1"></button> + </li> + </ul> + + <div ng-show="needReCheck && !checkingInProgress()"> + <button ng-click="$state.forceReload()" class="btn btn-medium btn-secondary"> + <span>Recheck</span> + </button> + </div> + <div ng-show="!needReCheck && !checkingInProgress()"> + <button ng-click="nextState()" class="btn btn-medium btn-prime"> + <span>Update</span> + </button> + </div> + </div> +</div> + <div id="updater-application" class="readiness-check-item" ng-show="updater.visible"> <div ng-hide="updater.processed"> <span class="spinner side"> @@ -546,8 +549,8 @@ </button> </header> <div class="modal-content" data-role="content"> - <div class="sync-login-wrap" style="padding: 0 4% 4rem;"> - <div class="login-header"> + <div class="delete-modal-wrap"> + <div class="delete-modal-header"> <span>Remove Product</span> </div> @@ -560,11 +563,11 @@ the product in the update grid. </div> <div class="form-actions"> - <div class="actions" style="padding: 5rem 0 0;"> + <div class="actions"> <button ng-click="removeExtension(extensionToRemove)" class="btn btn-large btn-prime"> <span>Remove</span> </button> - <button ng-click="closeThisDialog()" class="btn btn-large btn-cancel"> + <button ng-click="closeThisDialog()" class="btn btn-large btn-secondary"> <span>Cancel</span> </button> </div> -- GitLab From 87ec99d68ac7ab744b5ce1812ac802741d601548 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 11 Aug 2016 13:17:19 +0300 Subject: [PATCH 280/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../Framework/Api/Search/SearchCriteriaBuilder.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php b/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php index 6f4611d71fa..5f595802a98 100644 --- a/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php +++ b/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php @@ -25,6 +25,11 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder */ protected $filterGroupBuilder; + /** + * @var array + */ + private $filters = []; + /** * @param ObjectFactory $objectFactory * @param FilterGroupBuilder $filterGroupBuilder @@ -47,7 +52,11 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder */ public function create() { - $this->data[SearchCriteria::FILTER_GROUPS] = [$this->filterGroupBuilder->create()]; + foreach ($this->filters as $filter) { + $this->data[SearchCriteria::FILTER_GROUPS][] = $this->filterGroupBuilder->setFilters([]) + ->addFilter($filter) + ->create(); + } $this->data[SearchCriteria::SORT_ORDERS] = [$this->sortOrderBuilder->create()]; return parent::create(); } @@ -60,7 +69,7 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder */ public function addFilter(\Magento\Framework\Api\Filter $filter) { - $this->filterGroupBuilder->addFilter($filter); + $this->filters[] = $filter; return $this; } -- GitLab From 8fbf47bf82394703c21e5dce93045fda487e717e Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi <smankivskyi@magento.com> Date: Thu, 11 Aug 2016 13:20:28 +0300 Subject: [PATCH 281/838] MAGETWO-56012: SearchCriteria Unified Processing --- .../Framework/Api/Search/SearchCriteriaBuilder.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php b/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php index 6f4611d71fa..5f595802a98 100644 --- a/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php +++ b/lib/internal/Magento/Framework/Api/Search/SearchCriteriaBuilder.php @@ -25,6 +25,11 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder */ protected $filterGroupBuilder; + /** + * @var array + */ + private $filters = []; + /** * @param ObjectFactory $objectFactory * @param FilterGroupBuilder $filterGroupBuilder @@ -47,7 +52,11 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder */ public function create() { - $this->data[SearchCriteria::FILTER_GROUPS] = [$this->filterGroupBuilder->create()]; + foreach ($this->filters as $filter) { + $this->data[SearchCriteria::FILTER_GROUPS][] = $this->filterGroupBuilder->setFilters([]) + ->addFilter($filter) + ->create(); + } $this->data[SearchCriteria::SORT_ORDERS] = [$this->sortOrderBuilder->create()]; return parent::create(); } @@ -60,7 +69,7 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder */ public function addFilter(\Magento\Framework\Api\Filter $filter) { - $this->filterGroupBuilder->addFilter($filter); + $this->filters[] = $filter; return $this; } -- GitLab From ddcddce21b8b24157567a29bea5f30b046b9d68a Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 11 Aug 2016 13:55:08 +0300 Subject: [PATCH 282/838] MAGETWO-56572: Introduce and implement ShipmentCommentCreationInterface --- app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php index 811b0ad0653..37a933f97a2 100644 --- a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php +++ b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Api\Data; use Magento\Framework\Api\ExtensibleDataInterface; + /** * Invoice item interface. * -- GitLab From 748a9b596691e7a7c0d5d1663e7788282a756dc4 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Thu, 11 Aug 2016 14:27:09 +0300 Subject: [PATCH 283/838] MAGETWO-53570: PHP Version Check Improvement --- setup/pub/magento/setup/readiness-check.js | 56 +++++++++++----------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/setup/pub/magento/setup/readiness-check.js b/setup/pub/magento/setup/readiness-check.js index 167651b0620..b5a0937feaf 100644 --- a/setup/pub/magento/setup/readiness-check.js +++ b/setup/pub/magento/setup/readiness-check.js @@ -112,24 +112,6 @@ angular.module('readiness-check', []) updaterNoticeMessage: '' }; $scope.items = { - 'php-version': { - url:'index.php/environment/php-version', - params: $scope.actionFrom, - useGet: true, - show: function() { - $scope.startProgress(); - $scope.version.visible = true; - }, - process: function(data) { - $scope.version.processed = true; - angular.extend($scope.version, data); - $scope.updateOnProcessed($scope.version.responseType); - $scope.stopProgress(); - }, - fail: function() { - $scope.requestFailedHandler($scope.version); - } - }, 'php-settings': { url:'index.php/environment/php-settings', params: $scope.actionFrom, @@ -172,6 +154,24 @@ angular.module('readiness-check', []) }; if ($scope.actionFrom === 'installer') { + $scope.items['php-version'] = { + url:'index.php/environment/php-version', + params: $scope.actionFrom, + useGet: true, + show: function() { + $scope.startProgress(); + $scope.version.visible = true; + }, + process: function(data) { + $scope.version.processed = true; + angular.extend($scope.version, data); + $scope.updateOnProcessed($scope.version.responseType); + $scope.stopProgress(); + }, + fail: function() { + $scope.requestFailedHandler($scope.version); + } + }; $scope.items['file-permissions'] = { url:'index.php/environment/file-permissions', show: function() { @@ -259,22 +259,20 @@ angular.module('readiness-check', []) } }; } - } $scope.isCompleted = function() { - return $scope.version.processed - && $scope.settings.processed + var cronProcessed = ( + $scope.cronScript.processed + && ($scope.componentDependency.processed || !$scope.componentDependency.enabled) + && $scope.updater.processed + ); + + return $scope.settings.processed && $scope.extensions.processed && ($scope.permissions.processed || ($scope.actionFrom === 'updater')) - && ( - ( - $scope.cronScript.processed - && ($scope.componentDependency.processed || !$scope.componentDependency.enabled) - && $scope.updater.processed - ) - || ($scope.actionFrom !== 'updater') - ); + && ($scope.version.processed || ($scope.actionFrom === 'updater')) + && (cronProcessed || ($scope.actionFrom !== 'updater')); }; $scope.updateOnProcessed = function(value) { -- GitLab From 8a80791406f9968e549360942962fa1f5e4fa697 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Thu, 11 Aug 2016 14:56:32 +0300 Subject: [PATCH 284/838] MAGETWO-56490: Implement ShipmentPackageInterface --- .../Sales/Model/Order/Shipment/Package.php | 36 +++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 1 + 2 files changed, 37 insertions(+) create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/Package.php diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Package.php b/app/code/Magento/Sales/Model/Order/Shipment/Package.php new file mode 100644 index 00000000000..c9bc3371822 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/Package.php @@ -0,0 +1,36 @@ +<?php + +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Class Package + */ +class Package implements \Magento\Sales\Api\Data\ShipmentPackageInterface +{ + /** + * @var \Magento\Sales\Api\Data\ShipmentPackageExtensionInterface + */ + private $extensionAttributes; + + /** + * {@inheritdoc} + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * {@inheritdoc} + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentPackageExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + return $this; + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 4aba7ac4503..9786018d923 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -95,6 +95,7 @@ <preference for="Magento\Sales\Api\OrderInvoiceInterface" type="Magento\Sales\Model\OrderInvoice"/> <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <preference for="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" type="Magento\Sales\Model\Order\Shipment\TrackCreation"/> + <preference for="Magento\Sales\Api\Data\ShipmentPackageInterface" type="Magento\Sales\Model\Order\Shipment\Package"/> <type name="Magento\Sales\Model\ResourceModel\Report" shared="false"/> <type name="Magento\Sales\Model\Order\Pdf\Config\Reader"> <arguments> -- GitLab From 62dc9650f6e097a728c40e6b5c38fd1c98f7aa9f Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Thu, 11 Aug 2016 15:11:01 +0300 Subject: [PATCH 285/838] MAGETWO-56745: [Github] PayPal Express Checkout "Display on Shopping Cart -> NO" does not work --- .../Express/InContext/Minicart/Button.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Paypal/Block/Express/InContext/Minicart/Button.php b/app/code/Magento/Paypal/Block/Express/InContext/Minicart/Button.php index 56e32da15c9..6785b95dade 100644 --- a/app/code/Magento/Paypal/Block/Express/InContext/Minicart/Button.php +++ b/app/code/Magento/Paypal/Block/Express/InContext/Minicart/Button.php @@ -54,7 +54,6 @@ class Button extends Template implements ShortcutInterface private $session; /** - * Constructor * @param Context $context * @param ResolverInterface $localeResolver * @param ConfigFactory $configFactory @@ -80,6 +79,8 @@ class Button extends Template implements ShortcutInterface } /** + * Check `in_context` config value + * * @return bool */ private function isInContext() @@ -88,13 +89,27 @@ class Button extends Template implements ShortcutInterface } /** + * Check `visible_on_cart` config value + * + * @return bool + */ + private function isVisibleOnCart() + { + return (bool)(int) $this->config->getValue('visible_on_cart'); + } + + /** + * Check is Paypal In-Context Express Checkout button + * should render in cart/mini-cart + * * @return bool */ protected function shouldRender() { return $this->payment->isAvailable($this->session->getQuote()) && $this->isMiniCart - && $this->isInContext(); + && $this->isInContext() + && $this->isVisibleOnCart(); } /** -- GitLab From 444d906377d57e0b107aeebf16e3aef40f6c431c Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 16:14:10 +0300 Subject: [PATCH 286/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation --- .../Model/Order/Invoice/InvoiceValidator.php | 38 +++++++++++++ ...dator.php => InvoiceQuantityValidator.php} | 34 +++++------ .../Model/Order/InvoiceValidatorInterface.php | 25 --------- .../Sales/Model/Order/OrderValidator.php | 46 +++++++-------- .../Model/Order/OrderValidatorInterface.php | 2 +- .../Model/Order/Validation/CanInvoice.php | 56 +++++++++++++++++++ app/code/Magento/Sales/Model/OrderInvoice.php | 30 ++++++++-- app/code/Magento/Sales/Model/Validator.php | 51 +++++++++++++++++ .../Sales/Model/ValidatorInterface.php | 21 +++++++ .../Validator/InvoiceOrderTest.php} | 12 ++-- .../Unit/Model/Order/InvoiceValidatorTest.php | 2 +- app/code/Magento/Sales/etc/di.xml | 5 ++ 12 files changed, 241 insertions(+), 81 deletions(-) create mode 100644 app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php rename app/code/Magento/Sales/Model/Order/{InvoiceValidator.php => InvoiceQuantityValidator.php} (72%) delete mode 100644 app/code/Magento/Sales/Model/Order/InvoiceValidatorInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php create mode 100644 app/code/Magento/Sales/Model/Validator.php create mode 100644 app/code/Magento/Sales/Model/ValidatorInterface.php rename app/code/Magento/Sales/Test/Unit/Model/Order/{OrderValidatorTest.php => Invoice/Validator/InvoiceOrderTest.php} (90%) diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php new file mode 100644 index 00000000000..089443c1f08 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Invoice; + +use Magento\Sales\Api\Data\InvoiceInterface; + +/** + * Class InvoiceValidatorRunner + */ +class InvoiceValidator +{ + /** + * @var \Magento\Sales\Model\Validator + */ + private $validator; + + /** + * InvoiceValidatorRunner constructor. + * @param \Magento\Sales\Model\Validator $validator + */ + public function __construct(\Magento\Sales\Model\Validator $validator) + { + $this->validator = $validator; + } + + /** + * @param InvoiceInterface $entity + * @param array $validators + * @return string[] + */ + public function validate(InvoiceInterface $entity, array $validators) + { + return $this->validator->validate($entity, $validators); + } +} \ No newline at end of file diff --git a/app/code/Magento/Sales/Model/Order/InvoiceValidator.php b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php similarity index 72% rename from app/code/Magento/Sales/Model/Order/InvoiceValidator.php rename to app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php index 35222599fc6..51e98f8277b 100644 --- a/app/code/Magento/Sales/Model/Order/InvoiceValidator.php +++ b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php @@ -9,42 +9,42 @@ namespace Magento\Sales\Model\Order; use Magento\Sales\Api\Data\InvoiceInterface; use Magento\Sales\Api\Data\InvoiceItemInterface; use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order\Invoice\Validator\InvoiceValidatorRunner; +use Magento\Sales\Model\ValidatorInterface; /** * Interface InvoiceValidatorInterface */ -class InvoiceValidator implements InvoiceValidatorInterface +class InvoiceQuantityValidator implements ValidatorInterface { /** - * @var OrderValidatorInterface + * @var InvoiceValidatorRunner */ - private $orderValidator; + private $invoiceValidatorRunner; + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; /** * InvoiceValidator constructor. - * @param OrderValidatorInterface $orderValidator + * @param InvoiceValidatorRunner $invoiceValidatorRunner */ - public function __construct(OrderValidatorInterface $orderValidator) + public function __construct(InvoiceValidatorRunner $invoiceValidatorRunner, OrderRepositoryInterface $orderRepository) { - $this->orderValidator = $orderValidator; + $this->invoiceValidatorRunner = $invoiceValidatorRunner; + $this->orderRepository = $orderRepository; } /** * @param InvoiceInterface $invoice - * @param OrderInterface $order * @return array */ - public function validate(InvoiceInterface $invoice, OrderInterface $order) + public function validate($invoice) { - $messages = $this->checkQtyAvailability($invoice, $order); - - if (!$this->orderValidator->canInvoice($order)) { - $messages[] = __( - 'An invoice cannot be created when an order has a status of %1.', - $order->getStatus() - ); - } - return $messages; + $order = $this->orderRepository->get($invoice->getOrderId()); + return $this->checkQtyAvailability($invoice, $order); } /** diff --git a/app/code/Magento/Sales/Model/Order/InvoiceValidatorInterface.php b/app/code/Magento/Sales/Model/Order/InvoiceValidatorInterface.php deleted file mode 100644 index 64b2f98dfe3..00000000000 --- a/app/code/Magento/Sales/Model/Order/InvoiceValidatorInterface.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Sales\Model\Order; - -use Magento\Sales\Api\Data\InvoiceInterface; -use Magento\Sales\Api\Data\OrderInterface; - -/** - * Interface InvoiceValidatorInterface - * - * @api - */ -interface InvoiceValidatorInterface -{ - /** - * @param InvoiceInterface $invoice - * @param OrderInterface $order - * @return array - */ - public function validate(InvoiceInterface $invoice, OrderInterface $order); -} diff --git a/app/code/Magento/Sales/Model/Order/OrderValidator.php b/app/code/Magento/Sales/Model/Order/OrderValidator.php index c4766711368..9dbe1034f93 100644 --- a/app/code/Magento/Sales/Model/Order/OrderValidator.php +++ b/app/code/Magento/Sales/Model/Order/OrderValidator.php @@ -3,40 +3,34 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Sales\Model\Order; use Magento\Sales\Api\Data\OrderInterface; -use Magento\Sales\Model\Order; +use Magento\Sales\Exception\DocumentValidationException; /** - * Order Validator - * + * Class OrderValidatorRunner */ -class OrderValidator implements OrderValidatorInterface +class OrderValidator { /** - * Retrieve order invoice availability - * - * @param OrderInterface $order - * @return bool + * @var \Magento\Sales\Model\Validator + */ + private $validator; + + public function __construct(\Magento\Sales\Model\Validator $validator) + { + $this->validator = $validator; + } + + /** + * @param OrderInterface $entity + * @param array $validators + * @return string[] + * @throws DocumentValidationException */ - public function canInvoice(OrderInterface $order) + public function validate(OrderInterface $entity, array $validators) { - if ($order->getState() === Order::STATE_PAYMENT_REVIEW || - $order->getState() === Order::STATE_HOLDED || - $order->getState() === Order::STATE_CANCELED || - $order->getState() === Order::STATE_COMPLETE || - $order->getState() === Order::STATE_CLOSED - ) { - return false; - }; - /** @var \Magento\Sales\Model\Order\Item $item */ - foreach ($order->getItems() as $item) { - if ($item->getQtyToInvoice() > 0 && !$item->getLockedDoInvoice()) { - return true; - } - } - return false; + return $this->validator->validate($entity, $validators); } -} +} \ No newline at end of file diff --git a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php index d0dcc38af64..6ed3bacc057 100644 --- a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php +++ b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php @@ -19,5 +19,5 @@ interface OrderValidatorInterface * @param OrderInterface $order * @return bool */ - public function canInvoice(OrderInterface $order); + public function validate(OrderInterface $order); } diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php new file mode 100644 index 00000000000..785ec5acdb7 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -0,0 +1,56 @@ +<?php +/** + * Created by PhpStorm. + * User: valdislav + * Date: 8/10/16 + * Time: 6:51 PM + */ + +namespace Magento\Sales\Model\Order\Validation; + + +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\ValidatorInterface; + +class CanInvoice implements ValidatorInterface +{ + /** + * @param OrderInterface $entity + * @return array + */ + public function validate($entity) + { + $messages = []; + if (!$this->canInvoice($entity)) { + $messages[] = __( + 'An invoice cannot be created when an order has a status of %1.', + $entity->getStatus() + ); + } + + return $messages; + } + + /** + * @param OrderInterface $order + * @return bool + */ + private function canInvoice(OrderInterface $order) { + if ($order->getState() === Order::STATE_PAYMENT_REVIEW || + $order->getState() === Order::STATE_HOLDED || + $order->getState() === Order::STATE_CANCELED || + $order->getState() === Order::STATE_COMPLETE || + $order->getState() === Order::STATE_CLOSED + ) { + return false; + }; + /** @var \Magento\Sales\Model\Order\Item $item */ + foreach ($order->getItems() as $item) { + if ($item->getQtyToInvoice() > 0 && !$item->getLockedDoInvoice()) { + return true; + } + } + return false; + } +} diff --git a/app/code/Magento/Sales/Model/OrderInvoice.php b/app/code/Magento/Sales/Model/OrderInvoice.php index b499b7028bc..e8cb28fca11 100644 --- a/app/code/Magento/Sales/Model/OrderInvoice.php +++ b/app/code/Magento/Sales/Model/OrderInvoice.php @@ -12,12 +12,15 @@ use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface; use Magento\Sales\Api\OrderInvoiceInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order\Config as OrderConfig; +use Magento\Sales\Model\Order\Invoice\InvoiceValidator; use Magento\Sales\Model\Order\Invoice\NotifierInterface; use Magento\Sales\Model\Order\InvoiceDocumentFactory; +use Magento\Sales\Model\Order\InvoiceQuantityValidator; use Magento\Sales\Model\Order\InvoiceRepository; -use Magento\Sales\Model\Order\InvoiceValidatorInterface; use Magento\Sales\Model\Order\OrderStateResolverInterface; use Magento\Sales\Model\Order\PaymentAdapterInterface; +use Magento\Sales\Model\Order\Validation\CanInvoice; +use Magento\Sales\Model\Order\OrderValidator; use Psr\Log\LoggerInterface; /** @@ -42,7 +45,7 @@ class OrderInvoice implements OrderInvoiceInterface private $invoiceDocumentFactory; /** - * @var InvoiceValidatorInterface + * @var InvoiceValidator */ private $invoiceValidator; @@ -76,12 +79,18 @@ class OrderInvoice implements OrderInvoiceInterface */ private $logger; + /** + * @var OrderValidator + */ + private $orderValidator; + /** * OrderInvoice constructor. * @param ResourceConnection $resourceConnection * @param OrderRepositoryInterface $orderRepository * @param InvoiceDocumentFactory $invoiceDocumentFactory - * @param InvoiceValidatorInterface $invoiceValidator + * @param InvoiceValidator $invoiceValidator + * @param OrderValidator $orderValidator * @param PaymentAdapterInterface $paymentAdapter * @param OrderStateResolverInterface $orderStateResolver * @param OrderConfig $config @@ -94,7 +103,8 @@ class OrderInvoice implements OrderInvoiceInterface ResourceConnection $resourceConnection, OrderRepositoryInterface $orderRepository, InvoiceDocumentFactory $invoiceDocumentFactory, - InvoiceValidatorInterface $invoiceValidator, + InvoiceValidator $invoiceValidator, + OrderValidator $orderValidator, PaymentAdapterInterface $paymentAdapter, OrderStateResolverInterface $orderStateResolver, OrderConfig $config, @@ -106,6 +116,7 @@ class OrderInvoice implements OrderInvoiceInterface $this->orderRepository = $orderRepository; $this->invoiceDocumentFactory = $invoiceDocumentFactory; $this->invoiceValidator = $invoiceValidator; + $this->orderValidator = $orderValidator; $this->paymentAdapter = $paymentAdapter; $this->orderStateResolver = $orderStateResolver; $this->config = $config; @@ -147,7 +158,16 @@ class OrderInvoice implements OrderInvoiceInterface ($appendComment && $notify), $arguments ); - $errorMessages = $this->invoiceValidator->validate($invoice, $order); + $errorMessages = array_merge( + $this->invoiceValidator->validate( + $invoice, + [InvoiceQuantityValidator::class] + ), + $this->orderValidator->validate( + $order, + [CanInvoice::class] + ) + ); if (!empty($errorMessages)) { throw new \Magento\Sales\Exception\DocumentValidationException( __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) diff --git a/app/code/Magento/Sales/Model/Validator.php b/app/code/Magento/Sales/Model/Validator.php new file mode 100644 index 00000000000..5c18fd24b58 --- /dev/null +++ b/app/code/Magento/Sales/Model/Validator.php @@ -0,0 +1,51 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model; + +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\ConfigurationMismatchException; + +/** + * Class ValidatorRunner + */ +class Validator +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * ValidatorRunner constructor. + * + * @param ObjectManager $objectManager + */ + public function __construct(ObjectManager $objectManager) + { + $this->objectManager = $objectManager; + } + + /** + * @inheritdoc + */ + public function validate($entity, array $validators) + { + $messages = []; + foreach ($validators as $validatorName) { + $validator = $this->objectManager->get($validatorName); + if (!$validator instanceof ValidatorInterface) { + throw new ConfigurationMismatchException( + __( + sprintf('Validator %s is not instance of general validator interface', $validatorName) + ) + ); + } + $messages = array_merge($messages, $validator->validate($entity)); + } + + return $messages; + } +} diff --git a/app/code/Magento/Sales/Model/ValidatorInterface.php b/app/code/Magento/Sales/Model/ValidatorInterface.php new file mode 100644 index 00000000000..a42f938ea87 --- /dev/null +++ b/app/code/Magento/Sales/Model/ValidatorInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model; + +use Magento\Sales\Exception\DocumentValidationException; + +/** + * Interface ValidatorInterface + */ +interface ValidatorInterface +{ + /** + * @param object $entity + * @return string[] + * @throws DocumentValidationException + */ + public function validate($entity); +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/OrderValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Validator/InvoiceOrderTest.php similarity index 90% rename from app/code/Magento/Sales/Test/Unit/Model/Order/OrderValidatorTest.php rename to app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Validator/InvoiceOrderTest.php index 905d7c7a5b3..6942567ec14 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/OrderValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Validator/InvoiceOrderTest.php @@ -4,14 +4,14 @@ * See COPYING.txt for license details. */ -namespace Magento\Sales\Test\Unit\Model\Order; +namespace Magento\Sales\Test\Unit\Model\Order\Invoice\Validator; use Magento\Sales\Model\Order; /** * Test for \Magento\Sales\Model\Order\OrderValidator class */ -class OrderValidatorTest extends \PHPUnit_Framework_TestCase +class InvoiceOrderTest extends \PHPUnit_Framework_TestCase { /** * @var \Magento\Sales\Model\Order\OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject @@ -47,7 +47,7 @@ class OrderValidatorTest extends \PHPUnit_Framework_TestCase ->setMethods(['getQtyToInvoice', 'getLockedDoInvoice']) ->getMockForAbstractClass(); - $this->model = new \Magento\Sales\Model\Order\OrderValidator(); + $this->model = new \Magento\Sales\Model\Order\Invoice\Validator\InvoiceOrder(); } /** @@ -64,7 +64,7 @@ class OrderValidatorTest extends \PHPUnit_Framework_TestCase ->method('getItems'); $this->assertEquals( false, - $this->model->canInvoice($this->orderMock) + $this->model->validate($this->orderMock) ); } @@ -95,7 +95,7 @@ class OrderValidatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals( false, - $this->model->canInvoice($this->orderMock) + $this->model->validate($this->orderMock) ); } @@ -125,7 +125,7 @@ class OrderValidatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $expectedResult, - $this->model->canInvoice($this->orderMock) + $this->model->validate($this->orderMock) ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php index 6fdfdb61b36..c8113721e4f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php @@ -58,7 +58,7 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $this->model = $this->objectManager->getObject( - \Magento\Sales\Model\Order\InvoiceValidator::class, + \Magento\Sales\Model\Order\InvoiceQuantityValidator::class, ['orderValidator' => $this->orderValidatorMock] ); } diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 383650c8688..ade1dc7631d 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -909,4 +909,9 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\Order\InvoiceValidator"> + <arguments> + <argument name="invoiceOrderValidator" xsi:type="object">Magento\Sales\Model\Invoice\Validator\InvoiceOrder</argument> + </arguments> + </type> </config> -- GitLab From 91c11fd77396709c53e22beac9ef705c41f14fab Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 11 Aug 2016 16:15:36 +0300 Subject: [PATCH 287/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../styles/less/pages/_readiness-check.less | 55 ++++++++----------- setup/pub/styles/setup.css | 2 +- .../setup/readiness-check/progress.phtml | 44 ++++++++------- 3 files changed, 47 insertions(+), 54 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less index e4da9c18d34..8458dcc9cf7 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less @@ -69,34 +69,37 @@ .extensions-information { margin-bottom: 5rem; + h3 { + font-size: @base__font-size; + margin-bottom: 1.3rem; + } .message:before { margin-top: 0; top: 1.8rem; } .message { - margin-bottom: 1rem; + margin-bottom: @indent__m; } .extensions-container { - padding: 0 2rem; + padding: 0 @indent__base; } .list { - margin-bottom: 1rem; - } + margin-bottom: @indent__s; - .list select { - cursor: pointer; - } - - .list select:disabled { - cursor: default; - background: #cccccc; - } + select { + cursor: pointer; - .list { - .abs-action-delete { + &:disabled { + background: @color-gray80; + cursor: default; + } + } + + .extension-delete { + &:extend(.abs-action-delete all); font-size: 1.7rem; padding-top: 0; } @@ -106,29 +109,17 @@ .delete-modal-wrap { padding: 0 4% @indent__xl; - .delete-modal-header { + h3 { .lib-font-size(34); + display: inline-block; font-weight: @font-weight__light; margin: 0 0 @indent__base; - - span { - display: inline-block; - padding: .9rem 0 0; - vertical-align: top; - } + padding: .9rem 0 0; + vertical-align: top; } - .form-actions { - display: table; - margin-top: -1.3rem; - - .links { - display: table-header-group; - } - - .actions { - padding: @indent__xl 0 0; - } + .actions { + padding: @indent__l 0 0; } } diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css index dd962921ad9..8986ce65460 100644 --- a/setup/pub/styles/setup.css +++ b/setup/pub/styles/setup.css @@ -3,4 +3,4 @@ * See COPYING.txt for license details. */ -.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.extensions-information{margin-bottom:5rem}.extensions-information .message:before{margin-top:0;top:1.8rem}.extensions-information .message{margin-bottom:1rem}.extensions-information .extensions-container{padding:0 2rem}.extensions-information .list{margin-bottom:1rem}.extensions-information .list select{cursor:pointer}.extensions-information .list select:disabled{cursor:default;background:#ccc}.extensions-information .list .abs-action-delete{font-size:1.7rem;padding-top:0}.delete-modal-wrap{padding:0 4% 4rem}.delete-modal-wrap .delete-modal-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.delete-modal-wrap .delete-modal-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.delete-modal-wrap .form-actions{display:table;margin-top:-1.3rem}.delete-modal-wrap .form-actions .links{display:table-header-group}.delete-modal-wrap .form-actions .actions{padding:4rem 0 0}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file +.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.extensions-information .list .extension-delete>span,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.extensions-information .list .extension-delete,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.extensions-information .list .extension-delete:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete,.extensions-information .list .extension-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after,.extensions-information .list .extension-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after,.extensions-information .list .extension-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.extensions-information{margin-bottom:5rem}.extensions-information h3{font-size:1.4rem;margin-bottom:1.3rem}.extensions-information .message:before{margin-top:0;top:1.8rem}.extensions-information .message{margin-bottom:2.5rem}.extensions-information .extensions-container{padding:0 2rem}.extensions-information .list{margin-bottom:1rem}.extensions-information .list select{cursor:pointer}.extensions-information .list select:disabled{background:#ccc;cursor:default}.extensions-information .list .extension-delete{font-size:1.7rem;padding-top:0}.delete-modal-wrap{padding:0 4% 4rem}.delete-modal-wrap h3{font-size:3.4rem;display:inline-block;font-weight:300;margin:0 0 2rem;padding:.9rem 0 0;vertical-align:top}.delete-modal-wrap .actions{padding:3rem 0 0}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 93f2cfdc04e..8e60b32aa15 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -45,7 +45,7 @@ the installation process. </div> <div class="extensions-container"> - <p><strong>Update these extension(s)</strong></p> + <h3>Update these extension(s)</h3> <ul class="list"> <li ng-repeat="extension in getExtensionsList()"> {{extension.name}} {{getCurrentVersion(extension.name)}} to @@ -58,9 +58,12 @@ value="{{version}}" >Version {{version}}</option> </select> - <button class="abs-action-delete" + <button class="extension-delete" + title="Delete" ng-click="openDialog(extension.name)" - ng-show="!checkingInProgress() && getObjectSize(getExtensionsList()) > 1"></button> + ng-show="!checkingInProgress() && getObjectSize(getExtensionsList()) > 1"> + <span>Delete</span> + </button> </li> </ul> @@ -544,33 +547,32 @@ <aside class="modal-popup modal-connect-signin _show" data-role="modal"> <div class="modal-inner-wrap"> <header class="modal-header"> - <button ng-click="closeThisDialog()" class="action-close" data-role="closeBtn" type="button"> + <button ng-click="closeThisDialog()" + title="Close" + class="action-close" + data-role="closeBtn" + type="button"> <span>Close</span> </button> </header> <div class="modal-content" data-role="content"> <div class="delete-modal-wrap"> - <div class="delete-modal-header"> - <span>Remove Product</span> - </div> + <h3>Remove Product</h3> - <div>Are you sure you want to remove “{{extensionToRemove}}†from - the list?</div> - <br> - <div> + <p>Are you sure you want to remove “{{extensionToRemove}}†from + the list?</p> + <p> Please be aware that removing this product will remove it from the current update wizard flow. You can update this product at a later time by selecting the product in the update grid. - </div> - <div class="form-actions"> - <div class="actions"> - <button ng-click="removeExtension(extensionToRemove)" class="btn btn-large btn-prime"> - <span>Remove</span> - </button> - <button ng-click="closeThisDialog()" class="btn btn-large btn-secondary"> - <span>Cancel</span> - </button> - </div> + </p> + <div class="actions"> + <button ng-click="removeExtension(extensionToRemove)" class="btn btn-large btn-prime"> + <span>Remove</span> + </button> + <button ng-click="closeThisDialog()" class="btn btn-large btn-secondary"> + <span>Cancel</span> + </button> </div> </div> </div> -- GitLab From 5f4819db2b2a06cf2e6ed92a6414a8877e0fdc45 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 11 Aug 2016 16:20:02 +0300 Subject: [PATCH 288/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../web/app/setup/styles/less/pages/_readiness-check.less | 8 ++++---- setup/pub/styles/setup.css | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less index 8458dcc9cf7..2d66cea8129 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less @@ -73,13 +73,13 @@ font-size: @base__font-size; margin-bottom: 1.3rem; } - .message:before { - margin-top: 0; - top: 1.8rem; - } .message { margin-bottom: @indent__m; + &:before { + margin-top: 0; + top: 1.8rem; + } } .extensions-container { diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css index 8986ce65460..03902c88152 100644 --- a/setup/pub/styles/setup.css +++ b/setup/pub/styles/setup.css @@ -3,4 +3,4 @@ * See COPYING.txt for license details. */ -.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.extensions-information .list .extension-delete>span,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.extensions-information .list .extension-delete,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.extensions-information .list .extension-delete:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete,.extensions-information .list .extension-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after,.extensions-information .list .extension-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after,.extensions-information .list .extension-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.extensions-information{margin-bottom:5rem}.extensions-information h3{font-size:1.4rem;margin-bottom:1.3rem}.extensions-information .message:before{margin-top:0;top:1.8rem}.extensions-information .message{margin-bottom:2.5rem}.extensions-information .extensions-container{padding:0 2rem}.extensions-information .list{margin-bottom:1rem}.extensions-information .list select{cursor:pointer}.extensions-information .list select:disabled{background:#ccc;cursor:default}.extensions-information .list .extension-delete{font-size:1.7rem;padding-top:0}.delete-modal-wrap{padding:0 4% 4rem}.delete-modal-wrap h3{font-size:3.4rem;display:inline-block;font-weight:300;margin:0 0 2rem;padding:.9rem 0 0;vertical-align:top}.delete-modal-wrap .actions{padding:3rem 0 0}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file +.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.extensions-information .list .extension-delete>span,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.extensions-information .list .extension-delete,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.extensions-information .list .extension-delete:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete,.extensions-information .list .extension-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after,.extensions-information .list .extension-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after,.extensions-information .list .extension-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.extensions-information{margin-bottom:5rem}.extensions-information h3{font-size:1.4rem;margin-bottom:1.3rem}.extensions-information .message{margin-bottom:2.5rem}.extensions-information .message:before{margin-top:0;top:1.8rem}.extensions-information .extensions-container{padding:0 2rem}.extensions-information .list{margin-bottom:1rem}.extensions-information .list select{cursor:pointer}.extensions-information .list select:disabled{background:#ccc;cursor:default}.extensions-information .list .extension-delete{font-size:1.7rem;padding-top:0}.delete-modal-wrap{padding:0 4% 4rem}.delete-modal-wrap h3{font-size:3.4rem;display:inline-block;font-weight:300;margin:0 0 2rem;padding:.9rem 0 0;vertical-align:top}.delete-modal-wrap .actions{padding:3rem 0 0}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file -- GitLab From 4bcc0b4ba63fbc718bb3e63bcd1231428902539f Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 11 Aug 2016 16:43:35 +0300 Subject: [PATCH 289/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../web/app/setup/styles/less/pages/_readiness-check.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less index 2d66cea8129..a52fb94cbbd 100644 --- a/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less +++ b/app/design/adminhtml/Magento/backend/web/app/setup/styles/less/pages/_readiness-check.less @@ -76,6 +76,7 @@ .message { margin-bottom: @indent__m; + &:before { margin-top: 0; top: 1.8rem; -- GitLab From fe8501c443d1dd8ffc1cb529c74682f468df0df9 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 11 Aug 2016 16:52:51 +0300 Subject: [PATCH 290/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- .../Test/Unit/Model/QuoteRepositoryTest.php | 69 ++++++++++--------- .../Tax/Model/Calculation/RateRepository.php | 2 +- .../Magento/Tax/Model/TaxRuleRepository.php | 2 +- app/code/Magento/Tax/etc/di.xml | 8 +-- 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php index 124104b9731..3bd838d9d4b 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php @@ -9,7 +9,9 @@ namespace Magento\Quote\Test\Unit\Model; use Magento\Framework\Api\SortOrder; use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface; +use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\QuoteRepository\LoadHandler; +use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -66,10 +68,16 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase */ private $collectionProcessor; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + private $objectManagerMock; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->objectManagerMock = $this->getMock(\Magento\Framework\ObjectManagerInterface::class); + \Magento\Framework\App\ObjectManager::setInstance($this->objectManagerMock); + $this->quoteFactoryMock = $this->getMock(\Magento\Quote\Model\QuoteFactory::class, ['create'], [], '', false); $this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); $this->quoteMock = $this->getMock( @@ -411,55 +419,48 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase $this->model->delete($this->quoteMock); } - /** - * @param int $direction - * @param string $expectedDirection - */ - public function testGetListSuccess() + public function testGetList() { - $this->markTestSkipped('MAGETWO-48531'); - $searchResult = $this->getMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class, [], [], '', false); - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); - $cartMock = $this->getMock(\Magento\Payment\Model\Cart::class, [], [], '', false); $pageSize = 10; + $collectionFactoryMock = $this->getMockBuilder(CollectionFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $collectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->quoteCollectionMock); + $cartMock = $this->getMock(CartInterface::class, [], [], '', false); + $this->loadHandlerMock->expects($this->once()) + ->method('load') + ->with($cartMock); + $this->objectManagerMock->expects($this->atLeastOnce()) + ->method('get') + ->willReturnOnConsecutiveCalls($collectionFactoryMock); + $searchResult = $this->getMock(\Magento\Quote\Api\Data\CartSearchResultsInterface::class, [], [], '', false); + $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); $this->searchResultsDataFactory ->expects($this->once()) ->method('create') - ->will($this->returnValue($searchResult)); + ->willReturn($searchResult); - $searchResult - ->expects($this->once()) - ->method('setSearchCriteria'); - - //back in getList() - $this->quoteCollectionMock->expects($this->once())->method('getSize')->willReturn($pageSize); - $searchResult->expects($this->once())->method('setTotalCount')->with($pageSize); $this->collectionProcessor->expects($this->once()) ->method('process') ->with($searchCriteriaMock, $this->quoteCollectionMock); + $this->extensionAttributesJoinProcessorMock->expects($this->once()) ->method('process') ->with( $this->isInstanceOf(\Magento\Quote\Model\ResourceModel\Quote\Collection::class) ); - - $this->quoteCollectionMock->expects($this->once())->method('getItems')->willReturn([$cartMock]); - $searchResult->expects($this->once())->method('setItems')->with([$cartMock]); - - $this->model = $this->getMock( - \Magento\Quote\Model\QuoteRepository::class, - ['getQuoteCollection'], - [ - 'quoteFactory' => $this->quoteFactoryMock, - 'storeManager' => $this->storeManagerMock, - 'quoteCollection' => $this->quoteCollectionMock, - 'searchResultsDataFactory' => $this->searchResultsDataFactory, - 'extensionAttributesJoinProcessor' => $this->extensionAttributesJoinProcessorMock, - 'collectionProcessor' => $this->collectionProcessor, - ] - ); - $this->model->expects($this->once())->method('getQuoteCollection')->willReturn($this->quoteCollectionMock); + $this->quoteCollectionMock->expects($this->atLeastOnce())->method('getItems')->willReturn([$cartMock]); + $searchResult->expects($this->once())->method('setTotalCount')->with($pageSize); + $this->quoteCollectionMock->expects($this->once()) + ->method('getSize') + ->willReturn($pageSize); + $searchResult->expects($this->once()) + ->method('setItems') + ->with([$cartMock]); $this->assertEquals($searchResult, $this->model->getList($searchCriteriaMock)); } diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index 34b746a7c0f..6cd1679b509 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -310,7 +310,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - '\Magento\Tax\Model\Api\TaxRate\SearchCrtieria\CollectionProcessor' + 'Magento\Tax\Model\Api\SearchCriteria\TaxRateCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php index 9d18ff01767..312fca035f0 100644 --- a/app/code/Magento/Tax/Model/TaxRuleRepository.php +++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php @@ -227,7 +227,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - '\Magento\Tax\Model\Api\TaxRule\SearchCrtieria\CollectionProcessor' + 'Magento\Tax\Model\Api\SearchCriteria\TaxRuleCollectionProcessor' ); } return $this->collectionProcessor; diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index a626c5525e9..81127204031 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -87,15 +87,15 @@ </type> <type name="Magento\Tax\Model\TaxRuleRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessor</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\TaxRuleCollectionProcessor</argument> </arguments> </type> <type name="Magento\Tax\Model\Calculation\RateRepository"> <arguments> - <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessor</argument> + <argument name="collectionProcessor" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\TaxRateCollectionProcessor</argument> </arguments> </type> - <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRateCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> + <virtualType name="Magento\Tax\Model\Api\SearchCriteria\TaxRateCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="filters" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRateFilterProcessor</item> @@ -158,7 +158,7 @@ </argument> </arguments> </virtualType> - <virtualType name="Magento\Tax\Model\Api\SearchCrtieria\TaxRuleCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> + <virtualType name="Magento\Tax\Model\Api\SearchCriteria\TaxRuleCollectionProcessor" type="Magento\Framework\Api\SearchCriteria\CollectionProcessor"> <arguments> <argument name="processors" xsi:type="array"> <item name="joins" xsi:type="object">Magento\Tax\Model\Api\SearchCriteria\CollectionProcessor\TaxRuleJoinProcessor</item> -- GitLab From 034c5fd51814576f41136feec6cd3da881014789 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Thu, 11 Aug 2016 16:57:10 +0300 Subject: [PATCH 291/838] MAGETWO-56083: SearchCriteria Unified Processing for Ui, Vault modules --- app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php index 7b5c77933ae..76c2e3cab00 100644 --- a/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php +++ b/app/code/Magento/Ui/Model/ResourceModel/BookmarkRepository.php @@ -5,7 +5,6 @@ */ namespace Magento\Ui\Model\ResourceModel; -use Magento\Framework\Api\SearchCriteria\CollectionProcessor; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SortOrder; @@ -181,7 +180,7 @@ class BookmarkRepository implements BookmarkRepositoryInterface { if (!$this->collectionProcessor) { $this->collectionProcessor = \Magento\Framework\App\ObjectManager::getInstance()->get( - CollectionProcessor::class + CollectionProcessorInterface::class ); } return $this->collectionProcessor; -- GitLab From 04474e59983db20ab048d86cf9432c149f6e6794 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 17:01:37 +0300 Subject: [PATCH 292/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation --- .../Model/Order/InvoiceQuantityValidator.php | 10 +-- .../Model/Order/OrderValidatorInterface.php | 23 ------ .../Model/Order/Validation/CanInvoice.php | 11 ++- ...t.php => InvoiceQuantityValidatorTest.php} | 76 ++++--------------- .../CanInvoiceTest.php} | 15 ++-- 5 files changed, 29 insertions(+), 106 deletions(-) delete mode 100644 app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php rename app/code/Magento/Sales/Test/Unit/Model/Order/{InvoiceValidatorTest.php => InvoiceQuantityValidatorTest.php} (66%) rename app/code/Magento/Sales/Test/Unit/Model/Order/{Invoice/Validator/InvoiceOrderTest.php => Validation/CanInvoiceTest.php} (89%) diff --git a/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php index 51e98f8277b..a7c10089689 100644 --- a/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php @@ -10,7 +10,6 @@ use Magento\Sales\Api\Data\InvoiceInterface; use Magento\Sales\Api\Data\InvoiceItemInterface; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\OrderRepositoryInterface; -use Magento\Sales\Model\Order\Invoice\Validator\InvoiceValidatorRunner; use Magento\Sales\Model\ValidatorInterface; /** @@ -18,10 +17,6 @@ use Magento\Sales\Model\ValidatorInterface; */ class InvoiceQuantityValidator implements ValidatorInterface { - /** - * @var InvoiceValidatorRunner - */ - private $invoiceValidatorRunner; /** * @var OrderRepositoryInterface */ @@ -29,11 +24,10 @@ class InvoiceQuantityValidator implements ValidatorInterface /** * InvoiceValidator constructor. - * @param InvoiceValidatorRunner $invoiceValidatorRunner + * @param OrderRepositoryInterface $orderRepository */ - public function __construct(InvoiceValidatorRunner $invoiceValidatorRunner, OrderRepositoryInterface $orderRepository) + public function __construct(OrderRepositoryInterface $orderRepository) { - $this->invoiceValidatorRunner = $invoiceValidatorRunner; $this->orderRepository = $orderRepository; } diff --git a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php deleted file mode 100644 index 6ed3bacc057..00000000000 --- a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Sales\Model\Order; - -use Magento\Sales\Api\Data\OrderInterface; - -/** - * Interface OrderValidatorInterface - * - * @api - */ -interface OrderValidatorInterface -{ - /** - * @param OrderInterface $order - * @return bool - */ - public function validate(OrderInterface $order); -} diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index 785ec5acdb7..0dcb99b18b1 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -1,18 +1,17 @@ <?php /** - * Created by PhpStorm. - * User: valdislav - * Date: 8/10/16 - * Time: 6:51 PM + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. */ - namespace Magento\Sales\Model\Order\Validation; - use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\ValidatorInterface; +/** + * Class CanInvoice + */ class CanInvoice implements ValidatorInterface { /** diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php similarity index 66% rename from app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php rename to app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php index c8113721e4f..19af7c28ddc 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php @@ -6,15 +6,16 @@ namespace Magento\Sales\Test\Unit\Model\Order; +use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order; /** * Test for \Magento\Sales\Model\Order\InvoiceValidator class */ -class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase +class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Sales\Model\Order\InvoiceValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Model\Order\InvoiceQuantityValidator|\PHPUnit_Framework_MockObject_MockObject */ private $model; @@ -23,15 +24,14 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase */ private $objectManager; - /** - * @var \Magento\Sales\Model\Order\OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $orderValidatorMock; - /** * @var \Magento\Sales\Api\Data\OrderInterface|\PHPUnit_Framework_MockObject_MockObject */ private $orderMock; + /** + * @var \Magento\Sales\Api\OrderRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderRepositoryMock; /** * @var \Magento\Sales\Api\Data\InvoiceInterface|\PHPUnit_Framework_MockObject_MockObject @@ -42,11 +42,6 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->orderValidatorMock = $this->getMockBuilder(\Magento\Sales\Model\Order\OrderValidatorInterface::class) - ->disableOriginalConstructor() - ->setMethods(['canInvoice']) - ->getMockForAbstractClass(); - $this->orderMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderInterface::class) ->disableOriginalConstructor() ->setMethods(['getStatus']) @@ -56,10 +51,13 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['getTotalQty', 'getItems']) ->getMockForAbstractClass(); - + $this->orderRepositoryMock = $this->getMockBuilder( + OrderRepositoryInterface::class + )->disableOriginalConstructor()->getMockForAbstractClass(); + $this->orderRepositoryMock->expects($this->any())->method('get')->willReturn($this->orderMock); $this->model = $this->objectManager->getObject( \Magento\Sales\Model\Order\InvoiceQuantityValidator::class, - ['orderValidator' => $this->orderValidatorMock] + ['orderRepository' => $this->orderRepositoryMock] ); } @@ -75,39 +73,9 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); - $this->orderValidatorMock->expects($this->once()) - ->method('canInvoice') - ->with($this->orderMock) - ->willReturn(true); - $this->assertEquals( - $expectedResult, - $this->model->validate($this->invoiceMock, $this->orderMock) - ); - } - - public function testValidateCanNotInvoiceOrder() - { - $orderStatus = 'Test Status'; - $expectedResult = [__('An invoice cannot be created when an order has a status of %1.', $orderStatus)]; - $invoiceItemMock = $this->getInvoiceItemMock(1, 1); - $this->invoiceMock->expects($this->once()) - ->method('getItems') - ->willReturn([$invoiceItemMock]); - - $orderItemMock = $this->getOrderItemMock(1, 1, true); - $this->orderMock->expects($this->once()) - ->method('getItems') - ->willReturn([$orderItemMock]); - $this->orderMock->expects($this->once()) - ->method('getStatus') - ->willReturn($orderStatus); - $this->orderValidatorMock->expects($this->once()) - ->method('canInvoice') - ->with($this->orderMock) - ->willReturn(false); $this->assertEquals( $expectedResult, - $this->model->validate($this->invoiceMock, $this->orderMock) + $this->model->validate($this->invoiceMock) ); } @@ -125,13 +93,9 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); - $this->orderValidatorMock->expects($this->once()) - ->method('canInvoice') - ->with($this->orderMock) - ->willReturn(true); $this->assertEquals( $expectedResult, - $this->model->validate($this->invoiceMock, $this->orderMock) + $this->model->validate($this->invoiceMock) ); } @@ -146,13 +110,9 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([]); - $this->orderValidatorMock->expects($this->once()) - ->method('canInvoice') - ->with($this->orderMock) - ->willReturn(true); $this->assertEquals( $expectedResult, - $this->model->validate($this->invoiceMock, $this->orderMock) + $this->model->validate($this->invoiceMock) ); } @@ -169,13 +129,9 @@ class InvoiceValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); - $this->orderValidatorMock->expects($this->once()) - ->method('canInvoice') - ->with($this->orderMock) - ->willReturn(true); $this->assertEquals( $expectedResult, - $this->model->validate($this->invoiceMock, $this->orderMock) + $this->model->validate($this->invoiceMock) ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Validator/InvoiceOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php similarity index 89% rename from app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Validator/InvoiceOrderTest.php rename to app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php index 6942567ec14..7d33050ad3a 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Validator/InvoiceOrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php @@ -11,10 +11,10 @@ use Magento\Sales\Model\Order; /** * Test for \Magento\Sales\Model\Order\OrderValidator class */ -class InvoiceOrderTest extends \PHPUnit_Framework_TestCase +class CanInvoiceTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Sales\Model\Order\OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Model\Order\Validation\CanInvoice|\PHPUnit_Framework_MockObject_MockObject */ private $model; @@ -47,7 +47,7 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase ->setMethods(['getQtyToInvoice', 'getLockedDoInvoice']) ->getMockForAbstractClass(); - $this->model = new \Magento\Sales\Model\Order\Invoice\Validator\InvoiceOrder(); + $this->model = new \Magento\Sales\Model\Order\Validation\CanInvoice(); } /** @@ -62,8 +62,7 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase ->willReturn($state); $this->orderMock->expects($this->never()) ->method('getItems'); - $this->assertEquals( - false, + $this->assertNotEmpty( $this->model->validate($this->orderMock) ); } @@ -93,8 +92,7 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase ->method('getItems') ->willReturn([]); - $this->assertEquals( - false, + $this->assertNotEmpty( $this->model->validate($this->orderMock) ); } @@ -124,8 +122,7 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase ->willReturn($itemLockedDoInvoice); $this->assertEquals( - $expectedResult, - $this->model->validate($this->orderMock) + $expectedResult, empty($this->model->validate($this->orderMock)) ); } -- GitLab From db7a17af6686a0a2f6c1d0aa653ab54fa90d32cf Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 11 Aug 2016 17:32:45 +0300 Subject: [PATCH 293/838] MAGETWO-56776: Select box show per page in customer's my account pages is not visible --- .../blank/Magento_Catalog/web/css/source/module/_toolbar.less | 2 -- .../luma/Magento_Catalog/web/css/source/module/_toolbar.less | 2 -- 2 files changed, 4 deletions(-) diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less index 7e6c9797e43..00b2c23450f 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/module/_toolbar.less @@ -50,8 +50,6 @@ } .limiter { - display: none; - .control { display: inline-block; } diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less index 44a40037029..ae8fcf50cc7 100644 --- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less +++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_toolbar.less @@ -115,8 +115,6 @@ } .limiter { - display: none; - &-options { margin: 0 5px 0 7px; width: auto; -- GitLab From 89f07565981b66f65ac6621ee122dce7c9710cfe Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 11 Aug 2016 17:39:06 +0300 Subject: [PATCH 294/838] MAGETWO-42535: JS validation errors are displayed not per option groups for Product with custom options on "create Order" Admin page --- lib/web/mage/validation.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index f61177188bd..1f233614f4e 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1489,7 +1489,12 @@ } //logic for checkboxes/radio if (element.is(':checkbox') || element.is(':radio')) { - errorPlacement = element.siblings('label').last(); + errorPlacement = element.parents('.control').children().last(); + + //fallback if group does not have .control parent + if (!errorPlacement.length) { + errorPlacement = element.siblings('label').last(); + } } //logic for control with tooltip if (element.siblings('.tooltip').length) { -- GitLab From 3b4ecd689b33d0e34f3a20dbd49a6cc13ebbb66b Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 11 Aug 2016 17:44:02 +0300 Subject: [PATCH 295/838] MAGETWO-55988: JS validation is absent if Merchant doesn't specify Shipping Method while creating Order in Admin --- .../templates/order/create/shipping/method/form.phtml | 4 ++-- .../web/css/source/module/order/_payment-shipping.less | 6 ++++++ .../Magento/backend/web/css/source/forms/_fields.less | 2 +- .../backend/web/css/source/forms/fields/_control-table.less | 2 +- .../Magento/backend/web/css/source/variables/_forms.less | 2 -- .../adminhtml/Magento/backend/web/css/styles-old.less | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml index 49e0d26f661..dd7433cc4f0 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/shipping/method/form.phtml @@ -10,7 +10,7 @@ <?php /** @var $block \Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Method\Form */ ?> <?php $_shippingRateGroups = $block->getShippingRates(); ?> <?php if ($_shippingRateGroups): ?> - <div id="order-shipping-method-choose" style="display:none"> + <div id="order-shipping-method-choose" class="control" style="display:none"> <dl class="admin__order-shipment-methods"> <?php foreach ($_shippingRateGroups as $code => $_rates): ?> <dt class="admin__order-shipment-methods-title"><?php echo $block->escapeHtml($block->getCarrierName($code)) ?></dt> @@ -30,7 +30,7 @@ <?php $_checked = $block->isMethodActive($_code) ? 'checked="checked"' : '' ?> <input <?php /* @escapeNotVerified */ echo $_radioProperty ?> value="<?php /* @escapeNotVerified */ echo $_code ?>" id="s_method_<?php /* @escapeNotVerified */ echo $_code ?>" <?php /* @escapeNotVerified */ echo $_checked ?> - class="admin__control-radio"/> + class="admin__control-radio required-entry"/> <label class="admin__field-label" for="s_method_<?php /* @escapeNotVerified */ echo $_code ?>"> <?php echo $block->escapeHtml($_rate->getMethodTitle() ? $_rate->getMethodTitle() : $_rate->getMethodDescription()) ?> - <strong> diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less index bb6f36b1b4f..d2e85bed314 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_payment-shipping.less @@ -75,6 +75,12 @@ } } +.order-shipping-method { + .admin__page-section-title > span { + &:extend(.validation-symbol all); + } +} + .shipping-description-wrapper { .price { font-weight: @font-weight__bold; 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 b409ba500b9..3a116deffe9 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 @@ -227,7 +227,7 @@ ._required > & { > span { &:after { - color: @field-label__required__color; + color: @validation__color; content: '*'; display: inline-block; font-size: @font-size__l; diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/fields/_control-table.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/fields/_control-table.less index 38bf5130b54..7ecaf06f247 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/fields/_control-table.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/fields/_control-table.less @@ -131,7 +131,7 @@ &._required { span { &:after { - color: @field-label__required__color; + color: @validation__color; content: '*'; } } diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_forms.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_forms.less index 56a6f632d56..d3361c14e5d 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_forms.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_forms.less @@ -16,7 +16,6 @@ @field-label__disabled__color: @color-gray65-almost; @field-label__font-size: @font-size__base; @field-label__line-height: @line-height__s; -@field-label__required__color: @color-phoenix; @field-note__color: @color-very-dark-gray-black; @field-note__font-size: @font-size__s; @field-scope__color: @color-dark-gray; @@ -69,7 +68,6 @@ @field-label__indent: 1rem; @field-label__disabled__color: @color-gray60; -@field-label__required__color: @color-phoenix; @field-collapsible__border-color: @color-gray80; diff --git a/app/design/adminhtml/Magento/backend/web/css/styles-old.less b/app/design/adminhtml/Magento/backend/web/css/styles-old.less index 2454f6b33f6..d6319ff95d4 100644 --- a/app/design/adminhtml/Magento/backend/web/css/styles-old.less +++ b/app/design/adminhtml/Magento/backend/web/css/styles-old.less @@ -1412,7 +1412,7 @@ span { &:after { - color: #eb5202; + color: #e22626; content: '*'; display: inline-block; font-size: 1.6rem; -- GitLab From f9f1534fac7730b41cfb3a13103b4d741c2bb8da Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 17:58:24 +0300 Subject: [PATCH 296/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation --- .../Model/Order/Validation/CanInvoiceTest.php | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php index 7d33050ad3a..31d4e6cde9e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php @@ -125,6 +125,30 @@ class CanInvoiceTest extends \PHPUnit_Framework_TestCase $expectedResult, empty($this->model->validate($this->orderMock)) ); } + + public function testValidateCanNotInvoiceOrder() + { + $orderStatus = 'Test Status'; + $expectedResult = [__('An invoice cannot be created when an order has a status of %1.', $orderStatus)]; + $orderItemMock = $orderItemMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderItemInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getId', 'getQtyToInvoice', 'isDummy', 'getSku']) + ->getMockForAbstractClass(); + $orderItemMock->expects($this->any())->method('getId')->willReturn(1); + $orderItemMock->expects($this->any())->method('getQtyToInvoice')->willReturn(0); + $orderItemMock->expects($this->any())->method('isDummy')->willReturn(true); + $orderItemMock->expects($this->any())->method('getSku')->willReturn(1); + $this->orderMock->expects($this->once()) + ->method('getItems') + ->willReturn([$orderItemMock]); + $this->orderMock->expects($this->once()) + ->method('getStatus') + ->willReturn($orderStatus); + $this->assertEquals( + $expectedResult, + $this->model->validate($this->orderMock) + ); + } /** * Data provider for testCanInvoice -- GitLab From 0b4d732c8b07343e200251bbbed3730836588116 Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Thu, 11 Aug 2016 18:06:45 +0300 Subject: [PATCH 297/838] MAGETWO-56495: Introduce and implement ShipmentNotifier --- .../Sales/Model/Order/Shipment/Notifier.php | 41 ++ .../Order/Shipment/NotifierInterface.php | 31 ++ .../Order/Shipment/Sender/EmailSender.php | 149 ++++++++ .../Model/Order/Shipment/SenderInterface.php | 29 ++ .../Order/Shipment/Sender/EmailSenderTest.php | 361 ++++++++++++++++++ 5 files changed, 611 insertions(+) create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/Notifier.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/NotifierInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/SenderInterface.php create mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Notifier.php b/app/code/Magento/Sales/Model/Order/Shipment/Notifier.php new file mode 100644 index 00000000000..21dd5ad4a58 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/Notifier.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Shipment notifier. + * + * @api + */ +class Notifier implements \Magento\Sales\Model\Order\Shipment\NotifierInterface +{ + /** + * @var \Magento\Sales\Model\Order\Shipment\SenderInterface[] + */ + private $senders; + + /** + * @param \Magento\Sales\Model\Order\Shipment\SenderInterface[] $senders + */ + public function __construct(array $senders = []) + { + $this->senders = $senders; + } + + /** + * {@inheritdoc} + */ + public function notify( + \Magento\Sales\Api\Data\OrderInterface $order, + \Magento\Sales\Api\Data\ShipmentInterface $shipment, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + $forceSyncMode = false + ) { + foreach ($this->senders as $sender) { + $sender->send($order, $shipment, $comment, $forceSyncMode); + } + } +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/NotifierInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/NotifierInterface.php new file mode 100644 index 00000000000..f34eb6178d0 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/NotifierInterface.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Interface for Shipment notifier. + * + * @api + */ +interface NotifierInterface +{ + /** + * Notifies customer. + * + * @param \Magento\Sales\Api\Data\OrderInterface $order + * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment + * @param bool $forceSyncMode + * + * @return void + */ + public function notify( + \Magento\Sales\Api\Data\OrderInterface $order, + \Magento\Sales\Api\Data\ShipmentInterface $shipment, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + $forceSyncMode = false + ); +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php b/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php new file mode 100644 index 00000000000..228a45ff16a --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/Sender/EmailSender.php @@ -0,0 +1,149 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment\Sender; + +use Magento\Sales\Model\Order\Email\Sender; +use Magento\Sales\Model\Order\Shipment\SenderInterface; + +/** + * Email notification sender for Shipment. + */ +class EmailSender extends Sender implements SenderInterface +{ + /** + * @var \Magento\Payment\Helper\Data + */ + private $paymentHelper; + + /** + * @var \Magento\Sales\Model\ResourceModel\Order\Shipment + */ + private $shipmentResource; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface + */ + private $globalConfig; + + /** + * @var \Magento\Framework\Event\ManagerInterface + */ + private $eventManager; + + /** + * @param \Magento\Sales\Model\Order\Email\Container\Template $templateContainer + * @param \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity $identityContainer + * @param \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory + * @param \Psr\Log\LoggerInterface $logger + * @param \Magento\Sales\Model\Order\Address\Renderer $addressRenderer + * @param \Magento\Payment\Helper\Data $paymentHelper + * @param \Magento\Sales\Model\ResourceModel\Order\Shipment $shipmentResource + * @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig + * @param \Magento\Framework\Event\ManagerInterface $eventManager + */ + public function __construct( + \Magento\Sales\Model\Order\Email\Container\Template $templateContainer, + \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity $identityContainer, + \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory, + \Psr\Log\LoggerInterface $logger, + \Magento\Sales\Model\Order\Address\Renderer $addressRenderer, + \Magento\Payment\Helper\Data $paymentHelper, + \Magento\Sales\Model\ResourceModel\Order\Shipment $shipmentResource, + \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig, + \Magento\Framework\Event\ManagerInterface $eventManager + ) { + parent::__construct( + $templateContainer, + $identityContainer, + $senderBuilderFactory, + $logger, + $addressRenderer + ); + + $this->paymentHelper = $paymentHelper; + $this->shipmentResource = $shipmentResource; + $this->globalConfig = $globalConfig; + $this->eventManager = $eventManager; + } + + /** + * Sends order shipment email to the customer. + * + * Email will be sent immediately in two cases: + * + * - if asynchronous email sending is disabled in global settings + * - if $forceSyncMode parameter is set to TRUE + * + * Otherwise, email will be sent later during running of + * corresponding cron job. + * + * @param \Magento\Sales\Api\Data\OrderInterface $order + * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment + * @param bool $forceSyncMode + * + * @return bool + */ + public function send( + \Magento\Sales\Api\Data\OrderInterface $order, + \Magento\Sales\Api\Data\ShipmentInterface $shipment, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + $forceSyncMode = false + ) { + $shipment->setSendEmail(true); + + if (!$this->globalConfig->getValue('sales_email/general/async_sending') || $forceSyncMode) { + $transport = [ + 'order' => $order, + 'shipment' => $shipment, + 'comment' => $comment ? $comment->getComment() : '', + 'billing' => $order->getBillingAddress(), + 'payment_html' => $this->getPaymentHtml($order), + 'store' => $order->getStore(), + 'formattedShippingAddress' => $this->getFormattedShippingAddress($order), + 'formattedBillingAddress' => $this->getFormattedBillingAddress($order) + ]; + + $this->eventManager->dispatch( + 'email_shipment_set_template_vars_before', + ['sender' => $this, 'transport' => $transport] + ); + + $this->templateContainer->setTemplateVars($transport); + + if ($this->checkAndSend($order)) { + $shipment->setEmailSent(true); + + $this->shipmentResource->saveAttribute($shipment, ['send_email', 'email_sent']); + + return true; + } + } else { + $shipment->setEmailSent(null); + + $this->shipmentResource->saveAttribute($shipment, 'email_sent'); + } + + $this->shipmentResource->saveAttribute($shipment, 'send_email'); + + return false; + } + + /** + * Returns payment info block as HTML. + * + * @param \Magento\Sales\Api\Data\OrderInterface $order + * + * @return string + */ + private function getPaymentHtml(\Magento\Sales\Api\Data\OrderInterface $order) + { + return $this->paymentHelper->getInfoBlockHtml( + $order->getPayment(), + $this->identityContainer->getStore()->getStoreId() + ); + } +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/SenderInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/SenderInterface.php new file mode 100644 index 00000000000..a030038b7b1 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/SenderInterface.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Interface for notification sender for Shipment. + */ +interface SenderInterface +{ + /** + * Sends notification to a customer. + * + * @param \Magento\Sales\Api\Data\OrderInterface $order + * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment + * @param bool $forceSyncMode + * + * @return bool + */ + public function send( + \Magento\Sales\Api\Data\OrderInterface $order, + \Magento\Sales\Api\Data\ShipmentInterface $shipment, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + $forceSyncMode = false + ); +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php new file mode 100644 index 00000000000..8373c7e57d0 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Sender/EmailSenderTest.php @@ -0,0 +1,361 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Order\Shipment\Sender; + +/** + * Unit test for email notification sender for Shipment. + * + * @SuppressWarnings(PHPMD.TooManyFields) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class EmailSenderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Model\Order\Shipment\Sender\EmailSender + */ + private $subject; + + /** + * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @var \Magento\Sales\Model\Order\Email\Sender|\PHPUnit_Framework_MockObject_MockObject + */ + private $senderMock; + + /** + * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + + /** + * @var \Magento\Sales\Api\Data\ShipmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentMock; + + /** + * @var \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $commentMock; + + /** + * @var \Magento\Sales\Model\Order\Address|\PHPUnit_Framework_MockObject_MockObject + */ + private $addressMock; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $globalConfigMock; + + /** + * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $eventManagerMock; + + /** + * @var \Magento\Payment\Model\Info|\PHPUnit_Framework_MockObject_MockObject + */ + private $paymentInfoMock; + + /** + * @var \Magento\Payment\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + */ + private $paymentHelperMock; + + /** + * @var \Magento\Sales\Model\ResourceModel\Order\Shipment|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentResourceMock; + + /** + * @var \Magento\Sales\Model\Order\Address\Renderer|\PHPUnit_Framework_MockObject_MockObject + */ + private $addressRendererMock; + + /** + * @var \Magento\Sales\Model\Order\Email\Container\Template|\PHPUnit_Framework_MockObject_MockObject + */ + private $templateContainerMock; + + /** + * @var \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity|\PHPUnit_Framework_MockObject_MockObject + */ + private $identityContainerMock; + + /** + * @var \Magento\Sales\Model\Order\Email\SenderBuilderFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $senderBuilderFactoryMock; + + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + protected function setUp() + { + $this->orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + ->setMethods(['getStoreId']) + ->disableOriginalConstructor() + ->getMock(); + + $this->storeMock->expects($this->any()) + ->method('getStoreId') + ->willReturn(1); + $this->orderMock->expects($this->any()) + ->method('getStore') + ->willReturn($this->storeMock); + + $this->senderMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Email\Sender::class) + ->disableOriginalConstructor() + ->setMethods(['send', 'sendCopyTo']) + ->getMock(); + + $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->shipmentMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Shipment::class) + ->disableOriginalConstructor() + ->setMethods(['setSendEmail', 'setEmailSent']) + ->getMock(); + + $this->commentMock = $this->getMockBuilder(\Magento\Sales\Api\Data\ShipmentCommentCreationInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->commentMock->expects($this->any()) + ->method('getComment') + ->willReturn('Comment text'); + + $this->addressMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Address::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->orderMock->expects($this->any()) + ->method('getBillingAddress') + ->willReturn($this->addressMock); + $this->orderMock->expects($this->any()) + ->method('getShippingAddress') + ->willReturn($this->addressMock); + + $this->globalConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->paymentInfoMock = $this->getMockBuilder(\Magento\Payment\Model\Info::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->orderMock->expects($this->any()) + ->method('getPayment') + ->willReturn($this->paymentInfoMock); + + $this->paymentHelperMock = $this->getMockBuilder(\Magento\Payment\Helper\Data::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->paymentHelperMock->expects($this->any()) + ->method('getInfoBlockHtml') + ->with($this->paymentInfoMock, 1) + ->willReturn('Payment Info Block'); + + $this->shipmentResourceMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order\Shipment::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->addressRendererMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Address\Renderer::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->addressRendererMock->expects($this->any()) + ->method('format') + ->with($this->addressMock, 'html') + ->willReturn('Formatted address'); + + $this->templateContainerMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Email\Container\Template::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->identityContainerMock = $this->getMockBuilder( + \Magento\Sales\Model\Order\Email\Container\ShipmentIdentity::class + ) + ->disableOriginalConstructor() + ->getMock(); + + $this->identityContainerMock->expects($this->any()) + ->method('getStore') + ->willReturn($this->storeMock); + + $this->senderBuilderFactoryMock = $this->getMockBuilder( + \Magento\Sales\Model\Order\Email\SenderBuilderFactory::class + ) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->subject = new \Magento\Sales\Model\Order\Shipment\Sender\EmailSender( + $this->templateContainerMock, + $this->identityContainerMock, + $this->senderBuilderFactoryMock, + $this->loggerMock, + $this->addressRendererMock, + $this->paymentHelperMock, + $this->shipmentResourceMock, + $this->globalConfigMock, + $this->eventManagerMock + ); + } + + /** + * @param int $configValue + * @param bool $forceSyncMode + * @param bool $isComment + * @param bool $emailSendingResult + * + * @dataProvider sendDataProvider + * + * @return void + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testSend($configValue, $forceSyncMode, $isComment, $emailSendingResult) + { + $this->globalConfigMock->expects($this->once()) + ->method('getValue') + ->with('sales_email/general/async_sending') + ->willReturn($configValue); + + if (!$isComment) { + $this->commentMock = null; + } + + $this->shipmentMock->expects($this->once()) + ->method('setSendEmail') + ->with(true); + + if (!$configValue || $forceSyncMode) { + $transport = [ + 'order' => $this->orderMock, + 'shipment' => $this->shipmentMock, + 'comment' => $isComment ? 'Comment text' : '', + 'billing' => $this->addressMock, + 'payment_html' => 'Payment Info Block', + 'store' => $this->storeMock, + 'formattedShippingAddress' => 'Formatted address', + 'formattedBillingAddress' => 'Formatted address', + ]; + + $this->eventManagerMock->expects($this->once()) + ->method('dispatch') + ->with( + 'email_shipment_set_template_vars_before', + [ + 'sender' => $this->subject, + 'transport' => $transport, + ] + ); + + $this->templateContainerMock->expects($this->once()) + ->method('setTemplateVars') + ->with($transport); + + $this->identityContainerMock->expects($this->once()) + ->method('isEnabled') + ->willReturn($emailSendingResult); + + if ($emailSendingResult) { + $this->senderBuilderFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->senderMock); + + $this->senderMock->expects($this->once()) + ->method('send'); + + $this->senderMock->expects($this->once()) + ->method('sendCopyTo'); + + $this->shipmentMock->expects($this->once()) + ->method('setEmailSent') + ->with(true); + + $this->shipmentResourceMock->expects($this->once()) + ->method('saveAttribute') + ->with($this->shipmentMock, ['send_email', 'email_sent']); + + $this->assertTrue( + $this->subject->send( + $this->orderMock, + $this->shipmentMock, + $this->commentMock, + $forceSyncMode + ) + ); + } else { + $this->shipmentResourceMock->expects($this->once()) + ->method('saveAttribute') + ->with($this->shipmentMock, 'send_email'); + + $this->assertFalse( + $this->subject->send( + $this->orderMock, + $this->shipmentMock, + $this->commentMock, + $forceSyncMode + ) + ); + } + } else { + $this->shipmentMock->expects($this->once()) + ->method('setEmailSent') + ->with(null); + + $this->shipmentResourceMock->expects($this->at(0)) + ->method('saveAttribute') + ->with($this->shipmentMock, 'email_sent'); + $this->shipmentResourceMock->expects($this->at(1)) + ->method('saveAttribute') + ->with($this->shipmentMock, 'send_email'); + + $this->assertFalse( + $this->subject->send( + $this->orderMock, + $this->shipmentMock, + $this->commentMock, + $forceSyncMode + ) + ); + } + } + + /** + * @return array + */ + public function sendDataProvider() + { + return [ + 'Successful sync sending with comment' => [0, false, true, true], + 'Successful sync sending without comment' => [0, false, false, true], + 'Failed sync sending with comment' => [0, false, true, false], + 'Successful forced sync sending with comment' => [1, true, true, true], + 'Async sending' => [1, false, false, false], + ]; + } +} -- GitLab From a43af2592bef09499cbf02c149fb3f4bc770e3a6 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 18:08:14 +0300 Subject: [PATCH 298/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation --- .../Model/Order/Invoice/InvoiceValidator.php | 4 +--- .../Invoice/InvoiceValidatorInterface.php | 21 +++++++++++++++++ .../Sales/Model/Order/OrderValidator.php | 7 ++---- .../Model/Order/OrderValidatorInterface.php | 23 +++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 7 ++---- 5 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php index 089443c1f08..21428cd6d4f 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php @@ -27,9 +27,7 @@ class InvoiceValidator } /** - * @param InvoiceInterface $entity - * @param array $validators - * @return string[] + * @inheritdoc */ public function validate(InvoiceInterface $entity, array $validators) { diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php new file mode 100644 index 00000000000..e1c830d0d58 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Invoice; + +use Magento\Sales\Api\Data\InvoiceInterface; + +/** + * Interface InvoiceValidatorInterface + */ +interface InvoiceValidatorInterface +{ + /** + * @param InvoiceInterface $entity + * @param array $validators + * @return string[] + */ + public function validate(InvoiceInterface $entity, array $validators); +} diff --git a/app/code/Magento/Sales/Model/Order/OrderValidator.php b/app/code/Magento/Sales/Model/Order/OrderValidator.php index 9dbe1034f93..9f1bb5f21e6 100644 --- a/app/code/Magento/Sales/Model/Order/OrderValidator.php +++ b/app/code/Magento/Sales/Model/Order/OrderValidator.php @@ -11,7 +11,7 @@ use Magento\Sales\Exception\DocumentValidationException; /** * Class OrderValidatorRunner */ -class OrderValidator +class OrderValidator implements OrderValidatorInterface { /** * @var \Magento\Sales\Model\Validator @@ -24,10 +24,7 @@ class OrderValidator } /** - * @param OrderInterface $entity - * @param array $validators - * @return string[] - * @throws DocumentValidationException + * @inheritdoc */ public function validate(OrderInterface $entity, array $validators) { diff --git a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php new file mode 100644 index 00000000000..df8a33cd596 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order; + +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Exception\DocumentValidationException; + +/** + * Interface OrderValidatorInterface + */ +interface OrderValidatorInterface +{ + /** + * @param OrderInterface $entity + * @param array $validators + * @return string[] + * @throws DocumentValidationException + */ + public function validate(OrderInterface $entity, array $validators); +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 66a961fece4..6ca50ce4119 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -96,6 +96,8 @@ <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <preference for="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" type="Magento\Sales\Model\Order\Shipment\TrackCreation"/> <preference for="Magento\Sales\Api\Data\ShipmentPackageInterface" type="Magento\Sales\Model\Order\Shipment\Package"/> + <preference for="Magento\Sales\Model\Order\OrderValidatorInterface" type="Magento\Sales\Model\Order\OrderValidator"/> + <preference for="Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface" type="Magento\Sales\Model\Order\Invoice\InvoiceValidator"/> <type name="Magento\Sales\Model\ResourceModel\Report" shared="false"/> <type name="Magento\Sales\Model\Order\Pdf\Config\Reader"> <arguments> @@ -915,9 +917,4 @@ </argument> </arguments> </type> - <type name="Magento\Sales\Model\Order\InvoiceValidator"> - <arguments> - <argument name="invoiceOrderValidator" xsi:type="object">Magento\Sales\Model\Invoice\Validator\InvoiceOrder</argument> - </arguments> - </type> </config> -- GitLab From 395d9b330d4619fc8179151bdb20386ed6291048 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Thu, 11 Aug 2016 18:23:01 +0300 Subject: [PATCH 299/838] MAGETWO-56490: Implement ShipmentPackageInterface --- app/code/Magento/Sales/Model/Order/Shipment/Package.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Package.php b/app/code/Magento/Sales/Model/Order/Shipment/Package.php index c9bc3371822..6f8f54336a2 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Package.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Package.php @@ -1,5 +1,4 @@ <?php - /** * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. @@ -8,6 +7,7 @@ namespace Magento\Sales\Model\Order\Shipment; /** * Class Package + * @api */ class Package implements \Magento\Sales\Api\Data\ShipmentPackageInterface { -- GitLab From 84c3d6496a0c5026d193a9ad28b0047dbca1f03f Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 18:33:39 +0300 Subject: [PATCH 300/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation --- .../Sales/Model/Order/Invoice/InvoiceValidatorInterface.php | 5 ++++- .../Magento/Sales/Model/Order/OrderValidatorInterface.php | 3 ++- app/code/Magento/Sales/Model/Validator.php | 5 ++++- app/code/Magento/Sales/etc/di.xml | 1 + 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php index e1c830d0d58..568019a40fc 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php @@ -6,6 +6,8 @@ namespace Magento\Sales\Model\Order\Invoice; use Magento\Sales\Api\Data\InvoiceInterface; +use Magento\Sales\Exception\DocumentValidationException; +use Magento\Sales\Model\ValidatorInterface; /** * Interface InvoiceValidatorInterface @@ -14,8 +16,9 @@ interface InvoiceValidatorInterface { /** * @param InvoiceInterface $entity - * @param array $validators + * @param ValidatorInterface[] $validators * @return string[] + * @throws DocumentValidationException */ public function validate(InvoiceInterface $entity, array $validators); } diff --git a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php index df8a33cd596..c5a9a6c1d32 100644 --- a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php +++ b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Model\Order; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Exception\DocumentValidationException; +use Magento\Sales\Model\ValidatorInterface; /** * Interface OrderValidatorInterface @@ -15,7 +16,7 @@ interface OrderValidatorInterface { /** * @param OrderInterface $entity - * @param array $validators + * @param ValidatorInterface[] $validators * @return string[] * @throws DocumentValidationException */ diff --git a/app/code/Magento/Sales/Model/Validator.php b/app/code/Magento/Sales/Model/Validator.php index 5c18fd24b58..0b7dbc5eb83 100644 --- a/app/code/Magento/Sales/Model/Validator.php +++ b/app/code/Magento/Sales/Model/Validator.php @@ -29,7 +29,10 @@ class Validator } /** - * @inheritdoc + * @param object $entity + * @param ValidatorInterface[] $validators + * @return string[] + * @throws ConfigurationMismatchException */ public function validate($entity, array $validators) { diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 6ca50ce4119..00dbb0b4226 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -98,6 +98,7 @@ <preference for="Magento\Sales\Api\Data\ShipmentPackageInterface" type="Magento\Sales\Model\Order\Shipment\Package"/> <preference for="Magento\Sales\Model\Order\OrderValidatorInterface" type="Magento\Sales\Model\Order\OrderValidator"/> <preference for="Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface" type="Magento\Sales\Model\Order\Invoice\InvoiceValidator"/> + <preference for="Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface" type="Magento\Sales\Model\Order\Shipment\ShipmentValidator"/> <type name="Magento\Sales\Model\ResourceModel\Report" shared="false"/> <type name="Magento\Sales\Model\Order\Pdf\Config\Reader"> <arguments> -- GitLab From 097714c01664e5eab6833fcf7cbe1589faa58f8a Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 18:34:09 +0300 Subject: [PATCH 301/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface --- .../Order/Shipment/ShipmentValidator.php | 36 ++++++ .../Shipment/ShipmentValidatorInterface.php | 24 ++++ .../Model/Order/ShipmentQuantityValidator.php | 103 ++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php new file mode 100644 index 00000000000..75239253d4c --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\ShipmentInterface; + +/** + * Class ShipmentValidator + */ +class ShipmentValidator implements ShipmentValidatorInterface +{ + /** + * @var \Magento\Sales\Model\Validator + */ + private $validator; + + /** + * InvoiceValidatorRunner constructor. + * @param \Magento\Sales\Model\Validator $validator + */ + public function __construct(\Magento\Sales\Model\Validator $validator) + { + $this->validator = $validator; + } + + /** + * @inheritdoc + */ + public function validate(ShipmentInterface $entity, array $validators) + { + return $this->validator->validate($entity, $validators); + } +} diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php new file mode 100644 index 00000000000..198a4019bf6 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Exception\DocumentValidationException; +use Magento\Sales\Model\ValidatorInterface; + +/** + * Interface ShipmentValidatorInterface + */ +interface ShipmentValidatorInterface +{ + /** + * @param ShipmentInterface $shipment + * @param ValidatorInterface[] $validators + * @return string[] + * @throws DocumentValidationException + */ + public function validate(ShipmentInterface $shipment, array $validators); +} diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php new file mode 100644 index 00000000000..7da9dfdc0cf --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order; + +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentItemInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Exception\DocumentValidationException; +use Magento\Sales\Model\ValidatorInterface; + +/** + * Class ShipmentQuantityValidator + */ +class ShipmentQuantityValidator implements ValidatorInterface +{ + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * InvoiceValidator constructor. + * @param OrderRepositoryInterface $orderRepository + */ + public function __construct( + OrderRepositoryInterface $orderRepository + ) { + $this->orderRepository = $orderRepository; + } + + /** + * @param ShipmentInterface $entity + * @return string[] + * @throws DocumentValidationException + */ + public function validate($entity) + { + $messages = []; + + $order = $this->orderRepository->get($entity->getOrderId()); + foreach ($entity->getItems() as $shipmentItem) { + $messages = array_merge($messages, $this->validateShipmentItem($shipmentItem, $order)); + } + + return $messages; + } + + /** + * @param ShipmentItemInterface $item + * @param OrderInterface $order + * @return string[] + */ + public function validateShipmentItem(ShipmentItemInterface $item, OrderInterface $order) + { + $messages = []; + $orderItem = $this->getOrderItemById($order, $item->getOrderItemId()); + if ($orderItem === null) { + return [__('We can not found item "%1".', $item->getOrderItemId())]; + } + if ($orderItem->getIsQtyDecimal()) { + $qty = (double)$item->getQty(); + } else { + $qty = (int)$item->getQty(); + } + $qty = $qty > 0 ? $qty : 0; + + if (!$this->isQtyAvailable($orderItem, $qty)) { + $messages[] =__('We found an invalid quantity to ship for item "%1".', $item->getName()); + } + + return $messages; + } + + /** + * @param OrderInterface $order + * @param $id + * @return \Magento\Sales\Api\Data\OrderItemInterface|null + */ + private function getOrderItemById(OrderInterface $order, $id) + { + foreach ($order->getItems() as $item) { + if ($item->getItemId() === $id) { + return $item; + } + } + + return null; + } + + /** + * @param Item $orderItem + * @param int $qty + * @return bool + */ + private function isQtyAvailable(Item $orderItem, $qty) + { + return $qty <= $orderItem->getQtyToShip() || $orderItem->isDummy(true); + } +} -- GitLab From 535dcfb87630196bd043b5f63d2fa8b95b4a1783 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 11 Aug 2016 18:51:12 +0300 Subject: [PATCH 302/838] MAGETWO-55271: Cover with Functional Tests --- .../Magento/Setup/Test/Block/Readiness.php | 27 ++++++++++++++++++- .../TestCase/ExtensionMultipleUpdateTest.php | 1 + 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php index fefc5af46ed..27b9a81ad37 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/Block/Readiness.php @@ -41,7 +41,21 @@ class Readiness extends Block * * @var string */ - protected $removeExtension = '//li//strong[contains(text(), \'%s\')]//..//button'; + protected $removeExtension = '//li[contains(text(), \'%s\')]//button'; + + /** + * Remove button on modal. + * + * @var string + */ + protected $removeExtensionButtonOnModal = "[ng-click*='removeExtension']"; + + /** + * Remove popup modal. + * + * @var string + */ + protected $popupRemoveModal = '.modal-popup'; /** * 'Completed!' message. @@ -137,6 +151,17 @@ class Readiness extends Block $this->_rootElement->find($removeExtension, Locator::SELECTOR_XPATH)->click(); } + /** + * Click Remove button on modal. + * + * @return void + */ + public function clickRemoveExtensionOnModal() + { + $this->_rootElement->find($this->removeExtensionButtonOnModal, Locator::SELECTOR_CSS)->click(); + $this->waitForElementNotVisible($this->popupRemoveModal, Locator::SELECTOR_CSS); + } + /** * Get Updater application check result. * diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php index bf74f107f16..8175dd27b5d 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/ExtensionMultipleUpdateTest.php @@ -96,6 +96,7 @@ class ExtensionMultipleUpdateTest extends AbstractExtensionTest /** @var Extension $removeExtension */ foreach ($removeExtensions as $removeExtension) { $this->setupWizard->getReadiness()->clickRemoveExtension($removeExtension); + $this->setupWizard->getReadiness()->clickRemoveExtensionOnModal(); } $this->setupWizard->getReadiness()->clickTryAgain(); -- GitLab From 6be787874c428e82d93a162dbe2bb5a5fb8991a3 Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Thu, 11 Aug 2016 19:00:17 +0300 Subject: [PATCH 303/838] MAGETWO-54054: Compiler performance optimization - MAGETWO-50778: [Github][PR] Add cache of configuration files list #1628 - refactoring - extending solution and applying to get getComposerJsonFiles --- .../Magento/Framework/Module/Dir/Reader.php | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/lib/internal/Magento/Framework/Module/Dir/Reader.php b/lib/internal/Magento/Framework/Module/Dir/Reader.php index 5bbc58fbf12..99bbe9ad834 100644 --- a/lib/internal/Magento/Framework/Module/Dir/Reader.php +++ b/lib/internal/Magento/Framework/Module/Dir/Reader.php @@ -47,11 +47,11 @@ class Reader protected $readFactory; /** - * Cache storage + * Found configuration files grouped by configuration types (filename). * * @var array */ - protected $cache = []; + private $fileIterators = []; /** * @param Dir $moduleDirs @@ -72,27 +72,42 @@ class Reader } /** - * Go through all modules and find configuration files of active modules + * Go through all modules and find configuration files of active modules. * * @param string $filename * @return FileIterator */ public function getConfigurationFiles($filename) { - if (isset($this->cache[$filename])) { - return $this->cache[$filename]; - } - return $this->cache[$filename] = $this->fileIteratorFactory->create($this->getFiles($filename, Dir::MODULE_ETC_DIR)); + return $this->getFilesIterator($filename, Dir::MODULE_ETC_DIR); } /** - * Go through all modules and find composer.json files of active modules + * Go through all modules and find composer.json files of active modules. * * @return FileIterator */ public function getComposerJsonFiles() { - return $this->fileIteratorFactory->create($this->getFiles('composer.json')); + return $this->getFilesIterator('composer.json'); + } + + /** + * Retrieve iterator for files with $filename from components located in component $subDir. + * + * @param $filename + * @param string $subDir + * + * @return FileIterator + */ + private function getFilesIterator($filename, $subDir = '') + { + if (!isset($this->fileIterators[$subDir][$filename])) { + $this->fileIterators[$subDir][$filename] = $this->fileIteratorFactory->create( + $this->getFiles($filename, $subDir) + ); + } + return $this->fileIterators[$subDir][$filename]; } /** @@ -106,9 +121,9 @@ class Reader { $result = []; foreach ($this->modulesList->getNames() as $moduleName) { - $moduleEtcDir = $this->getModuleDir($subDir, $moduleName); - $file = $moduleEtcDir . '/' . $filename; - $directoryRead = $this->readFactory->create($moduleEtcDir); + $moduleSubDir = $this->getModuleDir($subDir, $moduleName); + $file = $moduleSubDir . '/' . $filename; + $directoryRead = $this->readFactory->create($moduleSubDir); $path = $directoryRead->getRelativePath($file); if ($directoryRead->isExist($path)) { $result[] = $file; @@ -169,5 +184,6 @@ class Reader public function setModuleDir($moduleName, $type, $path) { $this->customModuleDirs[$moduleName][$type] = $path; + $this->fileIterators = []; } } -- GitLab From 0dd6d38f1156e5efb7092b3b88fa1325bf9877c7 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 11 Aug 2016 19:05:26 +0300 Subject: [PATCH 304/838] MAGETWO-49556: The REST API intermittently rejects shipments submitted via a POST with Invalid Quantity to Ship Error --- .../Sales/Model/Order/Shipment/Item.php | 47 ++++++++++++------- .../Sales/Model/Order/ShipmentFactory.php | 33 ++++++++++++- .../Unit/Model/Order/ShipmentFactoryTest.php | 17 +++++++ 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index c7fdca853b1..09b9d442ba7 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -9,8 +9,10 @@ namespace Magento\Sales\Model\Order\Shipment; use Magento\Framework\Api\AttributeValueFactory; +use Magento\Framework\App\ObjectManager; use Magento\Sales\Api\Data\ShipmentItemInterface; use Magento\Sales\Model\AbstractModel; +use Magento\Sales\Model\Order\ShipmentQuantityValidator; /** * @method \Magento\Sales\Model\ResourceModel\Order\Shipment\Item _getResource() @@ -44,6 +46,11 @@ class Item extends AbstractModel implements ShipmentItemInterface */ protected $_orderItemFactory; + /** + * @var ShipmentValidatorInterface + */ + private $shipmentValidator; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -151,22 +158,7 @@ class Item extends AbstractModel implements ShipmentItemInterface */ public function setQty($qty) { - if ($this->getOrderItem()->getIsQtyDecimal()) { - $qty = (double)$qty; - } else { - $qty = (int)$qty; - } - $qty = $qty > 0 ? $qty : 0; - /** - * Check qty availability - */ - if ($qty <= $this->getOrderItem()->getQtyToShip() || $this->getOrderItem()->isDummy(true)) { - $this->setData('qty', $qty); - } else { - throw new \Magento\Framework\Exception\LocalizedException( - __('We found an invalid quantity to ship for item "%1".', $this->getName()) - ); - } + $this->setData('qty', $qty); return $this; } @@ -174,13 +166,36 @@ class Item extends AbstractModel implements ShipmentItemInterface * Applying qty to order item * * @return $this + * @throws \Magento\Framework\Exception\LocalizedException */ public function register() { + $errorMessages = $this->getShipmentValidator()->validate( + $this->getShipment(), + [ShipmentQuantityValidator::class] + ); + if (!empty($errors)) { + throw new \Magento\Framework\Exception\LocalizedException( + __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } $this->getOrderItem()->setQtyShipped($this->getOrderItem()->getQtyShipped() + $this->getQty()); return $this; } + /** + * @return ShipmentValidatorInterface + * @deprecated + */ + private function getShipmentValidator() + { + if ($this->shipmentValidator === null) { + $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); + } + + return $this->shipmentValidator; + } + //@codeCoverageIgnoreStart /** * Returns additional_data diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 2ac012760ee..74dc5e1f7f6 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -5,6 +5,10 @@ */ namespace Magento\Sales\Model\Order; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\LocalizedException; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; + /** * Factory class for @see \Magento\Sales\Api\Data\ShipmentInterface */ @@ -31,6 +35,11 @@ class ShipmentFactory */ protected $instanceName; + /** + * @var ShipmentValidatorInterface + */ + private $shipmentValidator; + /** * Factory constructor. * @@ -72,6 +81,7 @@ class ShipmentFactory * @param \Magento\Sales\Model\Order $order * @param array $items * @return \Magento\Sales\Api\Data\ShipmentInterface + * @throws LocalizedException */ protected function prepareItems( \Magento\Sales\Api\Data\ShipmentInterface $shipment, @@ -129,7 +139,15 @@ class ShipmentFactory $item->setQty($qty); $shipment->addItem($item); } - + $errorMessages = $this->getShipmentValidator()->validate( + $shipment, + [ShipmentQuantityValidator::class] + ); + if (!empty($errors)) { + throw new \Magento\Framework\Exception\LocalizedException( + __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } return $shipment->setTotalQty($totalQty); } @@ -211,4 +229,17 @@ class ShipmentFactory return $item->getQtyToShip() > 0; } } + + /** + * @return ShipmentValidatorInterface + * @deprecated + */ + private function getShipmentValidator() + { + if ($this->shipmentValidator === null) { + $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); + } + + return $this->shipmentValidator; + } } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php index 3760934457a..df35aae943e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Test\Unit\Model\Order; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; /** * Unit test for shipment factory class. @@ -33,6 +34,11 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase */ protected $trackFactory; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentValidatorMock; + /** * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -67,6 +73,9 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase '', false ); + $this->shipmentValidatorMock = $this->getMockBuilder( + ShipmentValidatorInterface::class + )->getMockForAbstractClass(); $this->subject = $objectManager->getObject( \Magento\Sales\Model\Order\ShipmentFactory::class, @@ -75,6 +84,12 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase 'trackFactory' => $this->trackFactory ] ); + + $objectManager->setBackwardCompatibleProperty( + $this->subject, + 'shipmentValidator', + $this->shipmentValidatorMock + ); } /** @@ -181,6 +196,8 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase } } + $this->shipmentValidatorMock->expects($this->once())->method('validate')->willReturn([]); + $this->assertEquals($shipment, $this->subject->create($order, ['1' => 5], $tracks)); } -- GitLab From 2362f197fcd46fdc0b000c6236c47c01eadd6811 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 12 Aug 2016 10:36:47 +0300 Subject: [PATCH 305/838] MAGETWO-55268: Upgrade/Check Requirements process --- .../magento/setup/readiness-check/progress.phtml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 8e60b32aa15..24d5034d999 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -7,8 +7,6 @@ // @codingStandardsIgnoreFile ?> - - <div ng-switch="isCompleted()"> <div ng-switch-when="true" ng-switch="hasErrors"> @@ -38,7 +36,9 @@ </div> <div class="extensions-information" ng-if="$state.current.type == 'update' && getObjectSize(getExtensionsList()) > 0"> - <div class="message message-warning"> + <div class="message message-warning" + ng-show="componentDependency.processed && componentDependency.responseType != 'success'" + > We found some extensions with available version updates. We recommend that you update to the recommended versions or remove these extensions from the installation process. We found some extensions with available version updates. We recommend that you update to the recommended versions or remove these extensions from @@ -67,12 +67,12 @@ </li> </ul> - <div ng-show="needReCheck && !checkingInProgress()"> + <div ng-show="(needReCheck || hasErrors) && !checkingInProgress()"> <button ng-click="$state.forceReload()" class="btn btn-medium btn-secondary"> - <span>Recheck</span> + <span>Try Again</span> </button> </div> - <div ng-show="!needReCheck && !checkingInProgress()"> + <div ng-show="!needReCheck && !checkingInProgress() && !hasErrors"> <button ng-click="nextState()" class="btn btn-medium btn-prime"> <span>Update</span> </button> -- GitLab From 8f21503fbb3ab5ee93a1f5862901dfee0dcab4c3 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 12 Aug 2016 10:42:51 +0300 Subject: [PATCH 306/838] MAGETWO-56743: Unable to upgrade with split databases -- CR fixes --- app/code/Magento/Paypal/Setup/InstallSchema.php | 1 - app/code/Magento/Vault/Setup/InstallSchema.php | 1 - lib/internal/Magento/Framework/Module/Setup.php | 2 ++ 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Paypal/Setup/InstallSchema.php b/app/code/Magento/Paypal/Setup/InstallSchema.php index 517a3dcbb83..d0a07242ad7 100644 --- a/app/code/Magento/Paypal/Setup/InstallSchema.php +++ b/app/code/Magento/Paypal/Setup/InstallSchema.php @@ -142,7 +142,6 @@ class InstallSchema implements InstallSchemaInterface 'agreement_id', \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE )->addForeignKey( - // TODO: refactor without FK. $installer->getFkName('paypal_billing_agreement_order', 'order_id', 'sales_order', 'entity_id'), 'order_id', $installer->getTable('sales_order'), diff --git a/app/code/Magento/Vault/Setup/InstallSchema.php b/app/code/Magento/Vault/Setup/InstallSchema.php index 1990f5d4a0c..6f505d130e4 100644 --- a/app/code/Magento/Vault/Setup/InstallSchema.php +++ b/app/code/Magento/Vault/Setup/InstallSchema.php @@ -145,7 +145,6 @@ class InstallSchema implements InstallSchemaInterface ['unsigned' => true, 'nullable' => false, 'primary' => true], 'Payment token Id' )->addForeignKey( - // TODO: refactor without FK. $setup->getFkName( $setup->getTable(self::ORDER_PAYMENT_TO_PAYMENT_TOKEN_TABLE), 'order_payment_id', diff --git a/lib/internal/Magento/Framework/Module/Setup.php b/lib/internal/Magento/Framework/Module/Setup.php index e590e09320e..3a0b9801632 100644 --- a/lib/internal/Magento/Framework/Module/Setup.php +++ b/lib/internal/Magento/Framework/Module/Setup.php @@ -74,6 +74,8 @@ class Setup implements SetupInterface } /** + * Returns default setup connection instance + * * @return \Magento\Framework\DB\Adapter\AdapterInterface */ private function getDefaultConnection() -- GitLab From 4bf92baa6d2a624af5a357ddf4d3d23dc5f95200 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 12 Aug 2016 10:46:25 +0300 Subject: [PATCH 307/838] MAGETWO-55268: Upgrade/Check Requirements process --- setup/src/Magento/Setup/Model/PackagesData.php | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index ebb4f910469..8242ffa3759 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -9,6 +9,7 @@ use Magento\Framework\Composer\ComposerInformation; /** * Class PackagesData returns system packages and available for update versions + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PackagesData { -- GitLab From 13a6d7a8d2c1a89066fa6ddd56ca804a4e13c21b Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 10:54:06 +0300 Subject: [PATCH 308/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation - change test --- app/code/Magento/Sales/Model/Validator.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Model/Validator.php b/app/code/Magento/Sales/Model/Validator.php index 0b7dbc5eb83..7dd55e38f85 100644 --- a/app/code/Magento/Sales/Model/Validator.php +++ b/app/code/Magento/Sales/Model/Validator.php @@ -5,25 +5,25 @@ */ namespace Magento\Sales\Model; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\ConfigurationMismatchException; +use Magento\Framework\ObjectManagerInterface; /** - * Class ValidatorRunner + * Class Validator */ class Validator { /** - * @var ObjectManager + * @var ObjectManagerInterface */ private $objectManager; /** * ValidatorRunner constructor. * - * @param ObjectManager $objectManager + * @param ObjectManagerInterface $objectManager */ - public function __construct(ObjectManager $objectManager) + public function __construct(ObjectManagerInterface $objectManager) { $this->objectManager = $objectManager; } -- GitLab From f1fb6fb91858093e1a9adb68d479a3fabdbde989 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 12 Aug 2016 11:23:10 +0300 Subject: [PATCH 309/838] MAGETWO-56743: Unable to upgrade with split databases --- app/code/Magento/OfflineShipping/composer.json | 2 +- app/code/Magento/Sales/Setup/SalesSetup.php | 1 + app/code/Magento/Sales/Setup/UpgradeSchema.php | 10 +++++++--- app/code/Magento/SalesSequence/Setup/InstallSchema.php | 3 ++- lib/internal/Magento/Framework/Module/Setup.php | 1 + 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json index e9a759057d3..3c959b4dec7 100644 --- a/app/code/Magento/OfflineShipping/composer.json +++ b/app/code/Magento/OfflineShipping/composer.json @@ -8,7 +8,6 @@ "magento/module-backend": "100.2.*", "magento/module-shipping": "100.2.*", "magento/module-catalog": "101.1.*", - "magento/module-sales": "100.2.*", "magento/module-sales-rule": "100.2.*", "magento/module-directory": "100.2.*", "magento/module-quote": "100.2.*", @@ -16,6 +15,7 @@ }, "suggest": { "magento/module-checkout": "100.2.*", + "magento/module-sales": "100.2.*", "magento/module-offline-shipping-sample-data": "Sample Data version:100.2.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Sales/Setup/SalesSetup.php b/app/code/Magento/Sales/Setup/SalesSetup.php index 470abce8bf8..3a2c999678a 100644 --- a/app/code/Magento/Sales/Setup/SalesSetup.php +++ b/app/code/Magento/Sales/Setup/SalesSetup.php @@ -15,6 +15,7 @@ use Magento\Framework\Setup\ModuleDataSetupInterface; /** * Setup Model of Sales Module * @codeCoverageIgnore + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SalesSetup extends \Magento\Eav\Setup\EavSetup { diff --git a/app/code/Magento/Sales/Setup/UpgradeSchema.php b/app/code/Magento/Sales/Setup/UpgradeSchema.php index 502e2e99e29..b977cb28596 100644 --- a/app/code/Magento/Sales/Setup/UpgradeSchema.php +++ b/app/code/Magento/Sales/Setup/UpgradeSchema.php @@ -4,6 +4,7 @@ * See COPYING.txt for license details. */ namespace Magento\Sales\Setup; + use Magento\Framework\Setup\UpgradeSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; @@ -35,7 +36,8 @@ class UpgradeSchema implements UpgradeSchemaInterface 'product_id', 'catalog_product_entity', 'entity_id', - self::$connectionName) + self::$connectionName + ) ); //sales_bestsellers_aggregated_monthly $connection->dropForeignKey( @@ -45,7 +47,8 @@ class UpgradeSchema implements UpgradeSchemaInterface 'product_id', 'catalog_product_entity', 'entity_id', - self::$connectionName) + self::$connectionName + ) ); //sales_bestsellers_aggregated_yearly @@ -56,7 +59,8 @@ class UpgradeSchema implements UpgradeSchemaInterface 'product_id', 'catalog_product_entity', 'entity_id', - self::$connectionName) + self::$connectionName + ) ); $installer->endSetup(); diff --git a/app/code/Magento/SalesSequence/Setup/InstallSchema.php b/app/code/Magento/SalesSequence/Setup/InstallSchema.php index 10ac971eb2c..5da1dc1e6bf 100644 --- a/app/code/Magento/SalesSequence/Setup/InstallSchema.php +++ b/app/code/Magento/SalesSequence/Setup/InstallSchema.php @@ -100,7 +100,8 @@ class InstallSchema implements InstallSchemaInterface 'sales_sequence_profile', 'meta_id', 'sales_sequence_meta', - 'meta_id', self::$connectionName + 'meta_id', + self::$connectionName ), 'meta_id', $installer->getTable('sales_sequence_meta', self::$connectionName), diff --git a/lib/internal/Magento/Framework/Module/Setup.php b/lib/internal/Magento/Framework/Module/Setup.php index 3a0b9801632..7bd12bc89f1 100644 --- a/lib/internal/Magento/Framework/Module/Setup.php +++ b/lib/internal/Magento/Framework/Module/Setup.php @@ -144,6 +144,7 @@ class Setup implements SetupInterface * Check is table exists * * @param string $table + * @param string $connectionName * @return bool */ public function tableExists($table, $connectionName = ResourceConnection::DEFAULT_CONNECTION) -- GitLab From f97db4ddef110104ec3356abdc23f97bea689c34 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Fri, 12 Aug 2016 12:34:38 +0300 Subject: [PATCH 310/838] MAGETWO-55193: Extension Management with Marketplace data - Fix static --- .../Setup/Controller/InstallExtensionGrid.php | 27 +++++++++++----- setup/src/Magento/Setup/Model/Grid/Module.php | 31 +++++++++++++------ .../src/Magento/Setup/Model/PackagesData.php | 12 +++---- .../Setup/Test/Unit/Model/Grid/ModuleTest.php | 1 - .../Test/Unit/Model/PackagesDataTest.php | 1 + 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php b/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php index 7ec8ef19b08..706fbbcbac1 100644 --- a/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php +++ b/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php @@ -60,6 +60,25 @@ class InstallExtensionGrid extends AbstractActionController { $extensions = $this->packagesData->getPackagesForInstall(); $packages = isset($extensions['packages']) ? $extensions['packages'] : []; + $packages = $this->formatPackageList($packages); + + return new JsonModel( + [ + 'success' => true, + 'extensions' => array_values($packages), + 'total' => count($packages) + ] + ); + } + + /** + * Format package list + * + * @param array $packages + * @return array + */ + private function formatPackageList(array $packages) + { array_walk($packages, function (&$package) { $package['vendor'] = ucfirst($package['vendor']); $package['link'] = isset($package['extra']['x-magento-ext-package-link']) ? @@ -70,12 +89,6 @@ class InstallExtensionGrid extends AbstractActionController $package['extra']['x-magento-ext-type'] : $this->typeMapper->map($package['name'], $package['type']); }); - return new JsonModel( - [ - 'success' => true, - 'extensions' => array_values($packages), - 'total' => count($packages) - ] - ); + return $packages; } } diff --git a/setup/src/Magento/Setup/Model/Grid/Module.php b/setup/src/Magento/Setup/Model/Grid/Module.php index 2e481638d45..9373f090798 100644 --- a/setup/src/Magento/Setup/Model/Grid/Module.php +++ b/setup/src/Magento/Setup/Model/Grid/Module.php @@ -6,10 +6,8 @@ namespace Magento\Setup\Model\Grid; use Magento\Framework\Composer\ComposerInformation; -use Magento\Framework\Module\FullModuleList; use Magento\Framework\Module\ModuleList; use Magento\Framework\Module\PackageInfoFactory; -use Magento\Setup\Model\ObjectManagerProvider; use Magento\Setup\Model\PackagesData; /** @@ -36,14 +34,14 @@ class Module private $packageInfo; /** - * @var ObjectManagerProvider + * @var \Magento\Setup\Model\ObjectManagerProvider */ private $objectManagerProvider; /** * Full Module info * - * @var FullModuleList + * @var \Magento\Framework\Module\FullModuleList */ private $fullModuleList; @@ -66,17 +64,17 @@ class Module /** * @param ComposerInformation $composerInformation - * @param FullModuleList $fullModuleList + * @param \Magento\Framework\Module\FullModuleList $fullModuleList * @param ModuleList $moduleList - * @param ObjectManagerProvider $objectManagerProvider + * @param \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider * @param TypeMapper $typeMapper * @param PackagesData $packagesData */ public function __construct( ComposerInformation $composerInformation, - FullModuleList $fullModuleList, + \Magento\Framework\Module\FullModuleList $fullModuleList, ModuleList $moduleList, - ObjectManagerProvider $objectManagerProvider, + \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider, TypeMapper $typeMapper, PackagesData $packagesData ) { @@ -189,10 +187,23 @@ class Module foreach ($items as &$item) { $item['moduleName'] = $item['moduleName'] ?: $this->packageInfo->getModuleName($item['name']); $item['enable'] = $this->moduleList->has($item['moduleName']); - $vendorSource = $item['name'] == self::UNKNOWN_PACKAGE_NAME ? $item['moduleName'] : $item['name']; $item['vendor'] = ucfirst(current(preg_split('%[/_]%', $vendorSource))); + } + $items = $this->addExtraInfo($items); + return array_values($items); + } + + /** + * Add extra info to result array + * + * @param array $items + * @return array + */ + private function addExtraInfo(array $items) + { + foreach ($items as &$item) { $extraInfo = $this->packagesData->getPackageExtraInfo($item['name'], $item['version']); $item['product_name'] = isset($extraInfo['x-magento-ext-title']) ? $extraInfo['x-magento-ext-title'] : $item['name']; @@ -200,6 +211,6 @@ class Module $this->typeMapper->map($item['name'], ComposerInformation::MODULE_PACKAGE_TYPE); } - return array_values($items); + return $items; } } diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index d608827a529..4a37fb72421 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -5,8 +5,6 @@ */ namespace Magento\Setup\Model; -use Magento\Framework\Composer\ComposerInformation; - /** * Class PackagesData returns system packages and available for update versions */ @@ -22,7 +20,7 @@ class PackagesData /**#@-*/ /** - * @var ComposerInformation + * @var \Magento\Framework\Composer\ComposerInformation */ private $composerInformation; @@ -64,14 +62,14 @@ class PackagesData /** * PackagesData constructor. * - * @param ComposerInformation $composerInformation, + * @param \Magento\Framework\Composer\ComposerInformation $composerInformation, * @param \Magento\Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider, * @param \Magento\Setup\Model\PackagesAuth $packagesAuth, * @param \Magento\Framework\Filesystem $filesystem, * @param \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider */ public function __construct( - ComposerInformation $composerInformation, + \Magento\Framework\Composer\ComposerInformation $composerInformation, \Magento\Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider, \Magento\Setup\Model\PackagesAuth $packagesAuth, \Magento\Framework\Filesystem $filesystem, @@ -376,7 +374,7 @@ class PackagesData { $result = []; foreach ($packages as $package) { - if ($package['type'] == ComposerInformation::METAPACKAGE_PACKAGE_TYPE) { + if ($package['type'] == \Magento\Framework\Composer\ComposerInformation::METAPACKAGE_PACKAGE_TYPE) { if (isset($package['require'])) { foreach ($package['require'] as $key => $requirePackage) { $result[$key] = $package['name']; @@ -400,7 +398,7 @@ class PackagesData $packages = $this->getPackagesJson(); array_walk($packages, function ($packageVersions) { $package = array_shift($packageVersions); - if ($package['type'] == ComposerInformation::METAPACKAGE_PACKAGE_TYPE + if ($package['type'] == \Magento\Framework\Composer\ComposerInformation::METAPACKAGE_PACKAGE_TYPE && isset($package['require']) ) { foreach (array_keys($package['require']) as $key) { diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php index 71121a2140b..c0bcfb9b7b0 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php @@ -191,7 +191,6 @@ class ModuleTest extends \PHPUnit_Framework_TestCase ], ]); - $this->moduleListMock->expects(static::exactly(2)) ->method('has') ->willReturn(true); diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php index f4e21834a7f..3cb9a1617ec 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php @@ -13,6 +13,7 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Tests Magento\Setup\Model\PackagesData + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PackagesDataTest extends \PHPUnit_Framework_TestCase { -- GitLab From 5743ac12ed38b30788cc73316b9f11acfb02611a Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 12 Aug 2016 12:51:21 +0300 Subject: [PATCH 311/838] MAGETWO-46843: Inline translation unavailable for some templates in UI module --- .../view/base/web/templates/form/element/uploader/uploader.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html b/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html index 84381319ed2..63c34c1a433 100644 --- a/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html +++ b/app/code/Magento/Ui/view/base/web/templates/form/element/uploader/uploader.html @@ -22,7 +22,7 @@ <render args="tooltipTpl" if="$data.tooltip"/> <div class="admin__field-note" if="$data.notice" attr="id: noticeId"> - <span translate="notice"/> + <span html="notice"/> </div> <label class="admin__field-error" if="error" attr="for: uid" text="error"/> -- GitLab From 1f3a84448e69e36b374b62abf482aef706a731ba Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Fri, 12 Aug 2016 13:32:24 +0300 Subject: [PATCH 312/838] MAGETWO-55234: Image does not save when edited via right-click and "Insert/Edit Image" --- lib/web/tiny_mce/plugins/advimage/js/image.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/web/tiny_mce/plugins/advimage/js/image.js b/lib/web/tiny_mce/plugins/advimage/js/image.js index 7e3cf00eb00..f87c40ff8fc 100644 --- a/lib/web/tiny_mce/plugins/advimage/js/image.js +++ b/lib/web/tiny_mce/plugins/advimage/js/image.js @@ -184,6 +184,7 @@ var ImageDialog = { tinyMCEPopup.editor.execCommand('mceRepaint'); tinyMCEPopup.editor.focus(); tinyMCEPopup.close(); + ed.onChange.dispatch(ed); }, getAttrib : function(e, at) { -- GitLab From 8f498d0a22883a66cab6a15150be98f11a7f46be Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 14:01:01 +0300 Subject: [PATCH 313/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation - change test --- .../Model/Order/Invoice/InvoiceValidator.php | 2 +- .../Model/Order/InvoiceQuantityValidator.php | 6 ++-- .../Sales/Model/Order/OrderValidator.php | 8 +++-- .../Model/Order/Validation/CanInvoice.php | 5 +-- app/code/Magento/Sales/Model/Validator.php | 4 ++- .../Model/Order/Validation/CanInvoiceTest.php | 34 +++---------------- 6 files changed, 20 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php index 21428cd6d4f..4fed2a56cc3 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php @@ -33,4 +33,4 @@ class InvoiceValidator { return $this->validator->validate($entity, $validators); } -} \ No newline at end of file +} diff --git a/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php index a7c10089689..f0f468a3923 100644 --- a/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php @@ -32,11 +32,13 @@ class InvoiceQuantityValidator implements ValidatorInterface } /** - * @param InvoiceInterface $invoice - * @return array + * @inheritdoc */ public function validate($invoice) { + if ($invoice->getOrderId() === null) { + return [__('OrderId in invoice document is required')]; + } $order = $this->orderRepository->get($invoice->getOrderId()); return $this->checkQtyAvailability($invoice, $order); } diff --git a/app/code/Magento/Sales/Model/Order/OrderValidator.php b/app/code/Magento/Sales/Model/Order/OrderValidator.php index 9f1bb5f21e6..8208af96c93 100644 --- a/app/code/Magento/Sales/Model/Order/OrderValidator.php +++ b/app/code/Magento/Sales/Model/Order/OrderValidator.php @@ -9,7 +9,7 @@ use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Exception\DocumentValidationException; /** - * Class OrderValidatorRunner + * Class OrderValidator */ class OrderValidator implements OrderValidatorInterface { @@ -18,6 +18,10 @@ class OrderValidator implements OrderValidatorInterface */ private $validator; + /** + * OrderValidator constructor. + * @param \Magento\Sales\Model\Validator $validator + */ public function __construct(\Magento\Sales\Model\Validator $validator) { $this->validator = $validator; @@ -30,4 +34,4 @@ class OrderValidator implements OrderValidatorInterface { return $this->validator->validate($entity, $validators); } -} \ No newline at end of file +} diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index 0dcb99b18b1..dffff83b97f 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -22,10 +22,7 @@ class CanInvoice implements ValidatorInterface { $messages = []; if (!$this->canInvoice($entity)) { - $messages[] = __( - 'An invoice cannot be created when an order has a status of %1.', - $entity->getStatus() - ); + $messages[] = __('The order does not allow an invoice to be created.'); } return $messages; diff --git a/app/code/Magento/Sales/Model/Validator.php b/app/code/Magento/Sales/Model/Validator.php index 7dd55e38f85..b8d57ded297 100644 --- a/app/code/Magento/Sales/Model/Validator.php +++ b/app/code/Magento/Sales/Model/Validator.php @@ -10,6 +10,8 @@ use Magento\Framework\ObjectManagerInterface; /** * Class Validator + * + * @internal */ class Validator { @@ -19,7 +21,7 @@ class Validator private $objectManager; /** - * ValidatorRunner constructor. + * Validator constructor. * * @param ObjectManagerInterface $objectManager */ diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php index 31d4e6cde9e..dae95c4a758 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php @@ -122,31 +122,7 @@ class CanInvoiceTest extends \PHPUnit_Framework_TestCase ->willReturn($itemLockedDoInvoice); $this->assertEquals( - $expectedResult, empty($this->model->validate($this->orderMock)) - ); - } - - public function testValidateCanNotInvoiceOrder() - { - $orderStatus = 'Test Status'; - $expectedResult = [__('An invoice cannot be created when an order has a status of %1.', $orderStatus)]; - $orderItemMock = $orderItemMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderItemInterface::class) - ->disableOriginalConstructor() - ->setMethods(['getId', 'getQtyToInvoice', 'isDummy', 'getSku']) - ->getMockForAbstractClass(); - $orderItemMock->expects($this->any())->method('getId')->willReturn(1); - $orderItemMock->expects($this->any())->method('getQtyToInvoice')->willReturn(0); - $orderItemMock->expects($this->any())->method('isDummy')->willReturn(true); - $orderItemMock->expects($this->any())->method('getSku')->willReturn(1); - $this->orderMock->expects($this->once()) - ->method('getItems') - ->willReturn([$orderItemMock]); - $this->orderMock->expects($this->once()) - ->method('getStatus') - ->willReturn($orderStatus); - $this->assertEquals( - $expectedResult, - $this->model->validate($this->orderMock) + $expectedResult, $this->model->validate($this->orderMock) ); } @@ -158,10 +134,10 @@ class CanInvoiceTest extends \PHPUnit_Framework_TestCase public function canInvoiceDataProvider() { return [ - [0, null, false], - [-1, null, false], - [1, true, false], - [0.5, false, true], + [0, null, [__('The order does not allow an invoice to be created.')]], + [-1, null, [__('The order does not allow an invoice to be created.')]], + [1, true, [__('The order does not allow an invoice to be created.')]], + [0.5, false, []], ]; } } -- GitLab From cb578e98e28f2d0ce406627094f9d15d6b70b0c0 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 14:16:00 +0300 Subject: [PATCH 314/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation - change test --- app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php index f0f468a3923..9ae81dacb0a 100644 --- a/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/InvoiceQuantityValidator.php @@ -37,7 +37,7 @@ class InvoiceQuantityValidator implements ValidatorInterface public function validate($invoice) { if ($invoice->getOrderId() === null) { - return [__('OrderId in invoice document is required')]; + return [__('Order Id is required for invoice document')]; } $order = $this->orderRepository->get($invoice->getOrderId()); return $this->checkQtyAvailability($invoice, $order); -- GitLab From 7c971560ba14c6e6bcb7698ae9c93a6e632b627d Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 14:23:11 +0300 Subject: [PATCH 315/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation - change test --- app/code/Magento/Sales/Model/ValidatorInterface.php | 1 + .../Unit/Model/Order/InvoiceQuantityValidatorTest.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/app/code/Magento/Sales/Model/ValidatorInterface.php b/app/code/Magento/Sales/Model/ValidatorInterface.php index a42f938ea87..26f37f9873b 100644 --- a/app/code/Magento/Sales/Model/ValidatorInterface.php +++ b/app/code/Magento/Sales/Model/ValidatorInterface.php @@ -16,6 +16,7 @@ interface ValidatorInterface * @param object $entity * @return string[] * @throws DocumentValidationException + * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function validate($entity); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php index 19af7c28ddc..309d4c4b5ce 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php @@ -116,6 +116,15 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase ); } + public function testValidateNoOrder() + { + $expectedResult = [__('Order Id is required for invoice document')]; + $this->assertEquals( + $expectedResult, + $this->model->validate($this->invoiceMock) + ); + } + public function testValidateNoInvoiceItems() { $expectedResult = [__('You can\'t create an invoice without products.')]; -- GitLab From 0adc3c282bc2e44355e35f4848222770aaadeeea Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 14:23:52 +0300 Subject: [PATCH 316/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation - change test --- app/code/Magento/Sales/Model/ValidatorInterface.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/ValidatorInterface.php b/app/code/Magento/Sales/Model/ValidatorInterface.php index 26f37f9873b..6c50af2c685 100644 --- a/app/code/Magento/Sales/Model/ValidatorInterface.php +++ b/app/code/Magento/Sales/Model/ValidatorInterface.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Exception\DocumentValidationException; /** @@ -16,7 +17,7 @@ interface ValidatorInterface * @param object $entity * @return string[] * @throws DocumentValidationException - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws NoSuchEntityException */ public function validate($entity); } -- GitLab From 2aac2b2d7fea23e4c7d2d4baf6270779ff26857f Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 14:32:59 +0300 Subject: [PATCH 317/838] MAGETWO-56711: Refactoring Order Invoice Business logic validation - change test --- .../Model/Order/InvoiceQuantityValidatorTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php index 309d4c4b5ce..8c6a3df2efd 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php @@ -73,6 +73,9 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); + $this->invoiceMock->expects($this->exactly(2)) + ->method('getOrderId') + ->willReturn(1); $this->assertEquals( $expectedResult, $this->model->validate($this->invoiceMock) @@ -93,6 +96,9 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); + $this->invoiceMock->expects($this->exactly(2)) + ->method('getOrderId') + ->willReturn(1); $this->assertEquals( $expectedResult, $this->model->validate($this->invoiceMock) @@ -110,6 +116,9 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([]); + $this->invoiceMock->expects($this->exactly(2)) + ->method('getOrderId') + ->willReturn(1); $this->assertEquals( $expectedResult, $this->model->validate($this->invoiceMock) @@ -138,6 +147,9 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->once()) ->method('getItems') ->willReturn([$orderItemMock]); + $this->invoiceMock->expects($this->exactly(2)) + ->method('getOrderId') + ->willReturn(1); $this->assertEquals( $expectedResult, $this->model->validate($this->invoiceMock) -- GitLab From 7e9c8c9864b2b6638f109ad3141a91de1c27e2eb Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 14:56:29 +0300 Subject: [PATCH 318/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface --- .../Model/Order/ShipmentQuantityValidator.php | 5 ++ .../Sales/Model/Order/Validation/CanShip.php | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 app/code/Magento/Sales/Model/Order/Validation/CanShip.php diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index 7da9dfdc0cf..b84813d1e56 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model\Order; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\Data\ShipmentItemInterface; @@ -36,9 +37,13 @@ class ShipmentQuantityValidator implements ValidatorInterface * @param ShipmentInterface $entity * @return string[] * @throws DocumentValidationException + * @throws NoSuchEntityException */ public function validate($entity) { + if ($entity->getOrderId() === null) { + return [__('Order Id is required for shipment document')]; + } $messages = []; $order = $this->orderRepository->get($entity->getOrderId()); diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php new file mode 100644 index 00000000000..adb71e3aa1b --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Validation; + +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Exception\DocumentValidationException; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\ValidatorInterface; + +/** + * Class CanShip + */ +class CanShip implements ValidatorInterface +{ + /** + * @param OrderInterface $entity + * @return string[] + * @throws DocumentValidationException + * @throws NoSuchEntityException + */ + public function validate($entity) + { + $messages = []; + if (!$this->canShip($entity)) { + $messages[] = __('The order does not allow an shipment to be created.'); + } + + return $messages; + } + + /** + * @param OrderInterface $order + * @return bool + */ + private function canShip(OrderInterface $order) + { + if ($order->getState() === Order::STATE_PAYMENT_REVIEW || + $order->getState() === Order::STATE_HOLDED || + $order->getIsVirtual() || + $order->getState() === Order::STATE_CANCELED + ) { + return false; + } + + /** @var \Magento\Sales\Model\Order\Item $item */ + foreach ($order->getItems() as $item) { + if ($item->getQtyToShip() > 0 && !$item->getIsVirtual() && !$item->getLockedDoShip()) { + return true; + } + } + + return false; + } +} -- GitLab From d01340e13015af257c27feae7adcb84c1cfe2986 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 15:01:53 +0300 Subject: [PATCH 319/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface --- .../Model/Order/Validation/CanShipTest.php | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php new file mode 100644 index 00000000000..1e07a7194fc --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php @@ -0,0 +1,141 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Test\Unit\Model\Order\Shipment\Validator; + +use Magento\Sales\Model\Order; + +/** + * Test for \Magento\Sales\Model\Order\Validation\CanShip class + */ +class CanShipTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Model\Order\Validation\CanShip|\PHPUnit_Framework_MockObject_MockObject + */ + private $model; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManager; + + /** + * @var \Magento\Sales\Api\Data\OrderInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var \Magento\Sales\Api\Data\OrderItemInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderItemMock; + + protected function setUp() + { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->orderMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getStatus', 'getItems']) + ->getMockForAbstractClass(); + + $this->orderItemMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderItemInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getQtyToShip', 'getLockedDoShip']) + ->getMockForAbstractClass(); + + $this->model = new \Magento\Sales\Model\Order\Validation\CanShip(); + } + + /** + * @param string $state + * + * @dataProvider canShipWrongStateDataProvider + */ + public function testCanShipWrongState($state) + { + $this->orderMock->expects($this->any()) + ->method('getState') + ->willReturn($state); + $this->orderMock->expects($this->never()) + ->method('getItems'); + $this->assertNotEmpty( + $this->model->validate($this->orderMock) + ); + } + + /** + * Data provider for testCanShipWrongState + * @return array + */ + public function canShipWrongStateDataProvider() + { + return [ + [Order::STATE_PAYMENT_REVIEW], + [Order::STATE_HOLDED], + [Order::STATE_CANCELED], + ]; + } + + public function testCanShipNoItems() + { + $this->orderMock->expects($this->any()) + ->method('getState') + ->willReturn(Order::STATE_PROCESSING); + + $this->orderMock->expects($this->once()) + ->method('getItems') + ->willReturn([]); + + $this->assertNotEmpty( + $this->model->validate($this->orderMock) + ); + } + + /** + * @param float $qtyToShipment + * @param bool|null $itemLockedDoShipment + * @param bool $expectedResult + * + * @dataProvider canShipDataProvider + */ + public function testCanShip($qtyToShipment, $itemLockedDoShipment, $expectedResult) + { + $this->orderMock->expects($this->any()) + ->method('getState') + ->willReturn(Order::STATE_PROCESSING); + + $items = [$this->orderItemMock]; + $this->orderMock->expects($this->once()) + ->method('getItems') + ->willReturn($items); + $this->orderItemMock->expects($this->any()) + ->method('getQtyToShip') + ->willReturn($qtyToShipment); + $this->orderItemMock->expects($this->any()) + ->method('getLockedDoShip') + ->willReturn($itemLockedDoShipment); + + $this->assertEquals( + $expectedResult, $this->model->validate($this->orderMock) + ); + } + + /** + * Data provider for testCanShip + * + * @return array + */ + public function canShipDataProvider() + { + return [ + [0, null, [__('The order does not allow an shipment to be created.')]], + [-1, null, [__('The order does not allow an shipment to be created.')]], + [1, true, [__('The order does not allow an shipment to be created.')]], + [0.5, false, []], + ]; + } +} -- GitLab From b99bac10e9d6e833b6b7a40730d9934024717cd6 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 15:03:45 +0300 Subject: [PATCH 320/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface - grammar fix --- app/code/Magento/Sales/Model/Order/Validation/CanShip.php | 2 +- .../Sales/Test/Unit/Model/Order/Validation/CanShipTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php index adb71e3aa1b..da4c05ab737 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php @@ -26,7 +26,7 @@ class CanShip implements ValidatorInterface { $messages = []; if (!$this->canShip($entity)) { - $messages[] = __('The order does not allow an shipment to be created.'); + $messages[] = __('The order does not allow a shipment to be created.'); } return $messages; diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php index 1e07a7194fc..c31fd28b7b4 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php @@ -132,9 +132,9 @@ class CanShipTest extends \PHPUnit_Framework_TestCase public function canShipDataProvider() { return [ - [0, null, [__('The order does not allow an shipment to be created.')]], - [-1, null, [__('The order does not allow an shipment to be created.')]], - [1, true, [__('The order does not allow an shipment to be created.')]], + [0, null, [__('The order does not allow a shipment to be created.')]], + [-1, null, [__('The order does not allow a shipment to be created.')]], + [1, true, [__('The order does not allow a shipment to be created.')]], [0.5, false, []], ]; } -- GitLab From de793dbc61c129dc2ca81a63d8ed713165e3b5d7 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 15:08:00 +0300 Subject: [PATCH 321/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface - grammar fix --- app/code/Magento/Sales/Model/Order/Validation/CanShip.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php index da4c05ab737..30575cc734f 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php @@ -20,7 +20,6 @@ class CanShip implements ValidatorInterface * @param OrderInterface $entity * @return string[] * @throws DocumentValidationException - * @throws NoSuchEntityException */ public function validate($entity) { -- GitLab From 891bc759bff684b70e7e173974ca8643f89a8c18 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 15:18:45 +0300 Subject: [PATCH 322/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface - grammar fix --- app/code/Magento/Sales/Model/Order/Validation/CanShip.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php index 30575cc734f..cebdc4b0afe 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php @@ -19,7 +19,6 @@ class CanShip implements ValidatorInterface /** * @param OrderInterface $entity * @return string[] - * @throws DocumentValidationException */ public function validate($entity) { -- GitLab From 11d0f10288c868c70d15b1af225eaac07c97c828 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Fri, 12 Aug 2016 15:20:21 +0300 Subject: [PATCH 323/838] MAGETWO-56488: Introduce and implement ShipmentTrackCreationInterface --- .../Data/ShipmentTrackCreationInterface.php | 105 ------------------ .../Sales/Api/Data/ShipmentTrackInterface.php | 15 +++ .../Magento/Sales/Api/Data/TrackInterface.php | 15 --- .../Model/Order/Shipment/TrackCreation.php | 12 +- 4 files changed, 22 insertions(+), 125 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php index dcca11da20d..f3c3347534a 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php @@ -13,111 +13,6 @@ namespace Magento\Sales\Api\Data; */ interface ShipmentTrackCreationInterface extends TrackInterface { - /** - * Sets the weight for the shipment package. - * - * @param float $weight - * @return $this - */ - public function setWeight($weight); - - /** - * Gets the weight for the shipment package. - * - * @return float Weight. - */ - public function getWeight(); - - /** - * Sets the quantity for the shipment package. - * - * @param float $qty - * @return $this - */ - public function setQty($qty); - - /** - * Gets the quantity for the shipment package. - * - * @return float Quantity. - */ - public function getQty(); - - /** - * Sets the order_id for the shipment package. - * - * @param int $id - * @return $this - */ - public function setOrderId($id); - - /** - * Gets the order_id for the shipment package. - * - * @return int - */ - public function getOrderId(); - - /** - * Sets the track number for the shipment package. - * - * @param string $trackNumber - * @return $this - */ - public function setTrackNumber($trackNumber); - - /** - * Gets the track number for the shipment package. - * - * @return string Track number. - */ - public function getTrackNumber(); - - /** - * Sets the description for the shipment package. - * - * @param string $description - * @return $this - */ - public function setDescription($description); - - /** - * Gets the description for the shipment package. - * - * @return string Description. - */ - public function getDescription(); - - /** - * Sets the title for the shipment package. - * - * @param string $title - * @return $this - */ - public function setTitle($title); - - /** - * Gets the title for the shipment package. - * - * @return string Title. - */ - public function getTitle(); - - /** - * Sets the carrier code for the shipment package. - * - * @param string $code - * @return $this - */ - public function setCarrierCode($code); - - /** - * Gets the carrier code for the shipment package. - * - * @return string Carrier code. - */ - public function getCarrierCode(); - /** * Retrieve existing extension attributes object or create a new one. * diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php index e641d285bc5..c6c610433cb 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php @@ -63,6 +63,21 @@ interface ShipmentTrackInterface extends TrackInterface */ const UPDATED_AT = 'updated_at'; + /** + * Sets the order_id for the shipment package. + * + * @param int $id + * @return $this + */ + public function setOrderId($id); + + /** + * Gets the order_id for the shipment package. + * + * @return int + */ + public function getOrderId(); + /** * Gets the created-at timestamp for the shipment package. * diff --git a/app/code/Magento/Sales/Api/Data/TrackInterface.php b/app/code/Magento/Sales/Api/Data/TrackInterface.php index 5b48aee85b3..d082f6ca5e0 100644 --- a/app/code/Magento/Sales/Api/Data/TrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/TrackInterface.php @@ -43,21 +43,6 @@ interface TrackInterface extends \Magento\Framework\Api\ExtensibleDataInterface */ public function getQty(); - /** - * Sets the order_id for the shipment package. - * - * @param int $id - * @return $this - */ - public function setOrderId($id); - - /** - * Gets the order_id for the shipment package. - * - * @return int - */ - public function getOrderId(); - /** * Sets the track number for the shipment package. * diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index 4774ada6a5a..4c9f6d99afd 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -67,6 +67,7 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setWeight($weight) { $this->weight = $weight; + return $this; } /** @@ -83,6 +84,7 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setQty($qty) { $this->qty = $qty; + return $this; } /** @@ -99,6 +101,7 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setOrderId($orderId) { $this->orderId = $orderId; + return $this; } /** @@ -115,6 +118,7 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setTrackNumber($trackNumber) { $this->trackNumber = $trackNumber; + return $this; } /** @@ -131,6 +135,7 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setDescription($description) { $this->description = $description; + return $this; } /** @@ -147,6 +152,7 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setTitle($title) { $this->title = $title; + return $this; } /** @@ -163,12 +169,11 @@ class TrackCreation implements ShipmentTrackCreationInterface public function setCarrierCode($carrierCode) { $this->carrierCode = $carrierCode; + return $this; } /** * {@inheritdoc} - * - * @return \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface|null */ public function getExtensionAttributes() { @@ -177,9 +182,6 @@ class TrackCreation implements ShipmentTrackCreationInterface /** * {@inheritdoc} - * - * @param \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes - * @return $this */ public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes) { -- GitLab From 02e33e1998ccfde10afb52bf9fab0bf84bad7b4c Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 12 Aug 2016 15:33:18 +0300 Subject: [PATCH 324/838] MAGETWO-49556: The REST API intermittently rejects shipments submitted via a POST with Invalid Quantity to Ship Error - fix typo --- app/code/Magento/Sales/Model/Order/Shipment/Item.php | 2 +- app/code/Magento/Sales/Model/Order/ShipmentFactory.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index 09b9d442ba7..ec1b2940fbf 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -174,7 +174,7 @@ class Item extends AbstractModel implements ShipmentItemInterface $this->getShipment(), [ShipmentQuantityValidator::class] ); - if (!empty($errors)) { + if (!empty($errorMessages)) { throw new \Magento\Framework\Exception\LocalizedException( __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) ); diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 74dc5e1f7f6..518f3909cd7 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -143,7 +143,7 @@ class ShipmentFactory $shipment, [ShipmentQuantityValidator::class] ); - if (!empty($errors)) { + if (!empty($errorMessages)) { throw new \Magento\Framework\Exception\LocalizedException( __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) ); -- GitLab From dd2084187d63ef0783735f28ab6cb8e3cb0cb179 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Fri, 12 Aug 2016 16:21:13 +0300 Subject: [PATCH 325/838] MAGETWO-56488: Introduce and implement ShipmentTrackCreationInterface --- .../Model/Order/Shipment/TrackCreation.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index 4c9f6d99afd..80129fae628 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -87,23 +87,6 @@ class TrackCreation implements ShipmentTrackCreationInterface return $this; } - /** - * {@inheritdoc} - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * {@inheritdoc} - */ - public function setOrderId($orderId) - { - $this->orderId = $orderId; - return $this; - } - /** * {@inheritdoc} */ -- GitLab From dca94825d8b65a35952df79f7333ff99cffd3b84 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Fri, 12 Aug 2016 17:37:42 +0300 Subject: [PATCH 326/838] MAGETWO-56080: SearchCriteria Unified Processing for Quote and Tax modules --- app/code/Magento/Tax/Model/Calculation/RateRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php index 6cd1679b509..7dede7589bc 100644 --- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php +++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php @@ -91,7 +91,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface RegionFactory $regionFactory, \Magento\Tax\Model\ResourceModel\Calculation\Rate $rateResource, \Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface $joinProcessor, - CollectionProcessorInterface $collectionProcessor + CollectionProcessorInterface $collectionProcessor = null ) { $this->converter = $converter; $this->rateRegistry = $rateRegistry; -- GitLab From 6a883194ce1b6f9adef7c90c153a86567780cf43 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Fri, 12 Aug 2016 17:58:20 +0300 Subject: [PATCH 327/838] MAGETWO-24139: Resolve TODO's related to Customer Service or create stories --- .../Test/Unit/Model/AttributeMetadatConverterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php b/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php index 3e617602ca7..9298e27d94e 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php @@ -148,8 +148,8 @@ class AttributeMetadatConverterTest extends \PHPUnit_Framework_TestCase $this->dataObjectHelper->expects($this->exactly(2)) ->method('populateWithArray') ->withConsecutive( - [$optionObject1, ['1'], '\Magento\Customer\Api\Data\OptionInterface'], - [$optionObject2, ['2'], '\Magento\Customer\Api\Data\OptionInterface'] + [$optionObject1, ['1'], 'Magento\Customer\Api\Data\OptionInterface'], + [$optionObject2, ['2'], 'Magento\Customer\Api\Data\OptionInterface'] ); $validationRule1 = $this->getMock(\Magento\Customer\Api\Data\ValidationRuleInterface::class); $validationRule2 = $this->getMock(\Magento\Customer\Api\Data\ValidationRuleInterface::class); -- GitLab From a1bfb2dcd2636ad02f2bc55d8275e9b7964f844f Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 12:12:04 -0500 Subject: [PATCH 328/838] MAGETWO-55925: Eliminate @escapeNotVerified in CatalogWidget Module This reverts commit 1103b06b16823f093721df330c485f7f45e6d9dd --- .../view/adminhtml/templates/product/widget/conditions.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml index 9f52576db7f..f5f2b898a97 100644 --- a/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml +++ b/app/code/Magento/CatalogWidget/view/adminhtml/templates/product/widget/conditions.phtml @@ -33,6 +33,6 @@ $fieldAttributes = $fieldId . ' class="' . $fieldClass . '" ' "Magento_Rule/rules", "prototype" ], function(VarienRulesForm){ - window.<?php echo $block->escapeHtml($block->getHtmlId()) ?> = new VarienRulesForm('<?php echo $block->escapeHtml($block->getHtmlId()) ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); + window.<?php echo $block->escapeJs($block->getHtmlId()) ?> = new VarienRulesForm('<?php echo $block->escapeJs($block->getHtmlId()) ?>', '<?php echo $block->escapeUrl($block->getNewChildUrl()) ?>'); }); </script> -- GitLab From 9c3e6be0dc81d3842223ce2962b80ab44ac9a4e8 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 12:16:59 -0500 Subject: [PATCH 329/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module This reverts commit 35e158cb4a9581c37f6762eff0ebe477f7371ea5 --- .../templates/system/config/validatevat.phtml | 4 ++-- .../view/adminhtml/templates/tab/cart.phtml | 14 +++++++------- .../view/frontend/templates/address/edit.phtml | 2 +- .../view/frontend/templates/form/register.phtml | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index 8b5a486a26b..be1e66d94b7 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -16,8 +16,8 @@ require(['prototype'], function(){ var validationMessage = $('validation_result'); params = { - country: $('<?php echo $block->escapeHtml($block->getMerchantCountryField()); ?>').value, - vat: $('<?php echo $block->escapeHtml($block->getMerchantVatNumberField()); ?>').value + country: $('<?php echo $block->escapeJs($block->getMerchantCountryField()); ?>').value, + vat: $('<?php echo $block->escapeJs($block->getMerchantVatNumberField()); ?>').value }; new Ajax.Request('<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>', { diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index 95a18f22191..f8ca555c2ad 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -29,19 +29,19 @@ require([ "Magento_Catalog/catalog/product/composite/configure" ], function(alert, confirm){ -<?php echo $block->escapeHtml($block->getJsObjectName()) ?>cartControl = { +<?php echo $block->escapeJs($block->getJsObjectName()) ?>cartControl = { reload: function (params) { if (!params) { params = {}; } - <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.reloadParams = params; - <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.reload(); - <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.reloadParams = {}; + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = params; + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reload(); + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = {}; }, configureItem: function (itemId) { - productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeHtml($listType) ?>', this.cbOnLoadIframe.bind(this)); - productConfigure.showItemConfiguration('<?php echo $block->escapeHtml($listType) ?>', itemId); + productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($listType) ?>', this.cbOnLoadIframe.bind(this)); + productConfigure.showItemConfiguration('<?php echo $block->escapeJs($listType) ?>', itemId); return false; }, @@ -81,7 +81,7 @@ $params = [ ]; ?> productConfigure.addListType( - '<?php echo $block->escapeHtml($listType) ?>', + '<?php echo $block->escapeJs($listType) ?>', { urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/configure', $params)) ?>', urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/update', $params)) ?>' diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index 3af2ad2f5bb..f4075b8516d 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -213,7 +213,7 @@ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeHtml($block->getRegionId()) ?>", + "defaultRegion": "<?php echo $block->escapeJs($block->getRegionId()) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index a2943c02ae6..b35727b26fb 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -210,7 +210,7 @@ require([ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeHtml($block->getFormData()->getRegionId()) ?>", + "defaultRegion": "<?php echo $block->escapeJs($block->getFormData()->getRegionId()) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> } } -- GitLab From e75b3ce497997e129b843ad928f2f66bfcf206b9 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 12:21:30 -0500 Subject: [PATCH 330/838] MAGETWO-55921: Eliminate @escapeNotVerified in Newsletter Module This reverts commit fa547432becf07cc939cc5a2edb67b59521f13fa --- .../Newsletter/view/adminhtml/templates/template/edit.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index 9f32fc9a8e4..61bfd057d45 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -176,9 +176,9 @@ require([ preview: function() { if (this.typeChange) { - $('preview_type').value = <?php echo $block->escapeHtml(TemplateTypesInterface::TYPE_TEXT) ?>; + $('preview_type').value = <?php echo $block->escapeJs(TemplateTypesInterface::TYPE_TEXT) ?>; } else { - $('preview_type').value = <?php echo $block->escapeHtml($block->getTemplateType()) ?>; + $('preview_type').value = <?php echo $block->escapeJs($block->getTemplateType()) ?>; } if (this.isEditor() && tinyMCE.get(this.id)) { tinyMCE.triggerSave(); @@ -219,7 +219,7 @@ require([ }; templateControl.init(); - templateControl.templateName = "<?php echo $block->escapeHtml($block->getJsTemplateName()) ?>"; + templateControl.templateName = "<?php echo $block->escapeJs($block->getJsTemplateName()) ?>"; //]]> }); -- GitLab From 70557f061826fa29a11da7e285c10b3834565864 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 12:22:06 -0500 Subject: [PATCH 331/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module This reverts commit 8acda82e7a3cf5a8ee4142dc7c5126783269949c --- .../adminhtml/templates/customer/edit/tab/wishlist.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index bc580057279..63377fcbbbe 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -21,13 +21,13 @@ if (!urlParams) { urlParams = ''; } - var url = <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; + var url = <?php echo $block->escapeJs($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; new Ajax.Updater( - <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.containerId, + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.containerId, url, { parameters: {form_key: FORM_KEY}, - onComplete: <?php echo $block->escapeHtml($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeHtml($block->getJsObjectName()) ?>), + onComplete: <?php echo $block->escapeJs($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeJs($block->getJsObjectName()) ?>), evalScripts:true } ); -- GitLab From 6b512596988f5f2d9f3102a56fbea17bff88ef13 Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Tue, 9 Aug 2016 17:33:17 -0500 Subject: [PATCH 332/838] MAGETWO-52555: [Github][PR] Don't hardcode the Magento_Backend::admin index #4396 --- .../Activate/Permissions/Tab/Webapi.php | 32 ++++++++++++------- .../Adminhtml/Integration/Edit/Tab/Webapi.php | 25 ++++++++++----- app/code/Magento/User/Block/Role/Tab/Edit.php | 29 ++++++++++------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php b/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php index 0c108b11a40..a75aec617f9 100644 --- a/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php +++ b/app/code/Magento/Integration/Block/Adminhtml/Integration/Activate/Permissions/Tab/Webapi.php @@ -147,12 +147,7 @@ class Webapi extends \Magento\Backend\Block\Widget\Form\Generic implements */ public function getResourcesTreeJson() { - $resources = $this->_resourceProvider->getAclResources(); - $configResource = array_filter($resources, function($node) { - return $node['id'] == 'Magento_Backend::admin'; - }); - $configResource = reset($configResource); - $aclResourcesTree = $this->_integrationData->mapResources($configResource['children']); + $aclResourcesTree = $this->_integrationData->mapResources($this->getAclResources()); return $this->encoder->encode($aclResourcesTree); } @@ -170,16 +165,29 @@ class Webapi extends \Magento\Backend\Block\Widget\Form\Generic implements { $selectedResources = $this->_selectedResources; if ($this->isEverythingAllowed()) { - $resources = $this->_resourceProvider->getAclResources(); - $configResource = array_filter($resources, function($node) { - return $node['id'] == 'Magento_Backend::admin'; - }); - $configResource = reset($configResource); - $selectedResources = $this->_getAllResourceIds($configResource['children']); + $selectedResources = $this->_getAllResourceIds($this->getAclResources()); } return $this->encoder->encode($selectedResources); } + /** + * Get lit of all ACL resources declared in the system. + * + * @return array + */ + private function getAclResources() + { + $resources = $this->_resourceProvider->getAclResources(); + $configResource = array_filter( + $resources, + function ($node) { + return $node['id'] == 'Magento_Backend::admin'; + } + ); + $configResource = reset($configResource); + return isset($configResource['children']) ? $configResource['children'] : []; + } + /** * Whether tree has any resources. * diff --git a/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php b/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php index d6eb51cd279..eca679a6f2d 100644 --- a/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php +++ b/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit/Tab/Webapi.php @@ -6,7 +6,6 @@ namespace Magento\Integration\Block\Adminhtml\Integration\Edit\Tab; -use Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info; use Magento\Integration\Controller\Adminhtml\Integration as IntegrationController; use Magento\Integration\Model\Integration as IntegrationModel; @@ -174,15 +173,25 @@ class Webapi extends \Magento\Backend\Block\Widget\Form\Generic implements * @return array */ public function getTree() + { + return $this->integrationData->mapResources($this->getAclResources()); + } + + /** + * Get lit of all ACL resources declared in the system. + * + * @return array + */ + private function getAclResources() { $resources = $this->aclResourceProvider->getAclResources(); - $configResource = array_filter($resources, function($node) { - return $node['id'] == 'Magento_Backend::admin'; - }); - $configResource = reset($configResource); - $rootArray = $this->integrationData->mapResources( - isset($configResource['children']) ? $configResource['children'] : [] + $configResource = array_filter( + $resources, + function ($node) { + return $node['id'] == 'Magento_Backend::admin'; + } ); - return $rootArray; + $configResource = reset($configResource); + return isset($configResource['children']) ? $configResource['children'] : []; } } diff --git a/app/code/Magento/User/Block/Role/Tab/Edit.php b/app/code/Magento/User/Block/Role/Tab/Edit.php index 3722bf73eaa..29b171df0cd 100644 --- a/app/code/Magento/User/Block/Role/Tab/Edit.php +++ b/app/code/Magento/User/Block/Role/Tab/Edit.php @@ -6,7 +6,6 @@ namespace Magento\User\Block\Role\Tab; -use Magento\Framework\App\ObjectManager; use Magento\User\Controller\Adminhtml\User\Role\SaveRole; /** @@ -93,7 +92,6 @@ class Edit extends \Magento\Backend\Block\Widget\Form implements \Magento\Backen */ public function setCoreRegistry(\Magento\Framework\Registry $coreRegistry) { - $this->coreRegistry = $coreRegistry; } @@ -105,7 +103,6 @@ class Edit extends \Magento\Backend\Block\Widget\Form implements \Magento\Backen */ public function getCoreRegistry() { - if (!($this->coreRegistry instanceof \Magento\Framework\Registry)) { return \Magento\Framework\App\ObjectManager::getInstance()->get(\Magento\Framework\Registry::class); } else { @@ -198,14 +195,24 @@ class Edit extends \Magento\Backend\Block\Widget\Form implements \Magento\Backen */ public function getTree() { - $resources = $this->aclResourceProvider->getAclResources(); - $configResource = array_filter($resources, function($node) { - return $node['id'] == 'Magento_Backend::admin'; - }); - $configResource = reset($configResource); - $rootArray = $this->integrationData->mapResources( - isset($configResource['children']) ? $configResource['children'] : [] + return $this->_integrationData->mapResources($this->getAclResources()); + } + + /** + * Get lit of all ACL resources declared in the system. + * + * @return array + */ + private function getAclResources() + { + $resources = $this->_aclResourceProvider->getAclResources(); + $configResource = array_filter( + $resources, + function ($node) { + return $node['id'] == 'Magento_Backend::admin'; + } ); - return $rootArray; + $configResource = reset($configResource); + return isset($configResource['children']) ? $configResource['children'] : []; } } -- GitLab From 92392ccd62aad24bfcd51e4653477139bdd403bc Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Wed, 10 Aug 2016 11:08:16 -0500 Subject: [PATCH 333/838] MAGETWO-52555: [Github][PR] Don't hardcode the Magento_Backend::admin index #4396 --- .../Block/Adminhtml/Integration/Edit/Tab/WebapiTest.php | 7 ++++--- .../Magento/User/Test/Unit/Block/Role/Tab/EditTest.php | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Integration/Test/Unit/Block/Adminhtml/Integration/Edit/Tab/WebapiTest.php b/app/code/Magento/Integration/Test/Unit/Block/Adminhtml/Integration/Edit/Tab/WebapiTest.php index 0c6d9b7fc7a..d4c60966ab2 100644 --- a/app/code/Magento/Integration/Test/Unit/Block/Adminhtml/Integration/Edit/Tab/WebapiTest.php +++ b/app/code/Magento/Integration/Test/Unit/Block/Adminhtml/Integration/Edit/Tab/WebapiTest.php @@ -155,7 +155,8 @@ class WebapiTest extends \PHPUnit_Framework_TestCase { $this->webapiBlock = $this->getWebapiBlock(); $resources = [ - 1 => [ 'children' => [1, 2, 3] ] + ['id' => 'Magento_Backend::admin', 'children' => ['resource1', 'resource2', 'resource3']], + ['id' => 'Invalid_Node', 'children' => ['resource4', 'resource5', 'resource6']] ]; $this->aclResourceProvider->expects($this->once()) ->method('getAclResources') @@ -163,7 +164,7 @@ class WebapiTest extends \PHPUnit_Framework_TestCase $rootArray = "rootArrayValue"; $this->integrationHelper->expects($this->once()) ->method('mapResources') - ->with([1, 2, 3]) + ->with(['resource1', 'resource2', 'resource3']) ->will($this->returnValue($rootArray)); $this->assertEquals($rootArray, $this->webapiBlock->getTree()); } @@ -197,7 +198,7 @@ class WebapiTest extends \PHPUnit_Framework_TestCase return [ 'root resource in array' => [ 2, - ['all_resources' => 0, 'resource'=>[2, 3]], + ['all_resources' => 0, 'resource' => [2, 3]], true ], 'root resource not in array' => [ diff --git a/app/code/Magento/User/Test/Unit/Block/Role/Tab/EditTest.php b/app/code/Magento/User/Test/Unit/Block/Role/Tab/EditTest.php index 271e0973e13..666bb2bc832 100644 --- a/app/code/Magento/User/Test/Unit/Block/Role/Tab/EditTest.php +++ b/app/code/Magento/User/Test/Unit/Block/Role/Tab/EditTest.php @@ -86,7 +86,10 @@ class EditTest extends \PHPUnit_Framework_TestCase public function testGetTree() { - $resources = ['resource1', 'resource2', 'resource3']; + $resources = [ + ['id' => 'Magento_Backend::admin', 'children' => ['resource1', 'resource2', 'resource3']], + ['id' => 'Invalid_Node', 'children' => ['resource4', 'resource5', 'resource6']] + ]; $mappedResources = ['mapped1', 'mapped2', 'mapped3']; $this->aclResourceProviderMock->expects($this->once())->method('getAclResources')->willReturn($resources); $this->integrationDataMock->expects($this->once())->method('mapResources')->willReturn($mappedResources); -- GitLab From 5aafeb77b3d7c402817cfbc16c0b298231d55eec Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 12:25:42 -0500 Subject: [PATCH 334/838] MAGETWO-55919: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module Applying escape functions in templates --- app/code/Magento/Captcha/view/adminhtml/templates/default.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index 905d9149140..1aceb9ff95d 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -44,7 +44,7 @@ require(["prototype", "mage/captcha"], function(){ //<![CDATA[ - var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeHtml($block->getFormId()) ?>'); + var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeJs($block->getFormId()) ?>'); $('captcha-reload').observe('click', function () { captcha.refresh(this); -- GitLab From 434574d9169222f86eda0962fb25a75c9658a1c0 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 12:56:12 -0500 Subject: [PATCH 335/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module This reverts commit 4b37e4ef959de654b82c9edc6cd918289dfb7ba1 --- .../catalog/category/widget/tree.phtml | 18 +++--- .../templates/instance/edit/layout.phtml | 59 +++++++++---------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml index 8ec14aff1db..32c7486d867 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -14,7 +14,7 @@ <script> require(['jquery', "prototype", "extjs/ext-tree-checkbox"], function(jQuery){ -var tree<?php echo $block->escapeHtml($block->getId()) ?>; +var tree<?php echo $block->escapeJs($block->getId()) ?>; var useMassaction = <?php /* @noEscape */ echo $block->getUseMassaction() ? 1 : 0; ?>; @@ -43,7 +43,7 @@ Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { if (firstLoad) { <?php if ($block->getNodeClickListener()): ?> - this.addListener('click', <?php echo $block->escapeHtml($block->getNodeClickListener()) ?>.createDelegate(this)); + this.addListener('click', <?php echo $block->escapeJs($block->getNodeClickListener()) ?>.createDelegate(this)); <?php endif; ?> } @@ -149,25 +149,25 @@ jQuery(function() }; categoryLoader.on("beforeload", function(treeLoader, node) { - $('<?php echo $block->escapeHtml($_divId); ?>').fire('category:beforeLoad', {treeLoader:treeLoader}); + $('<?php echo $block->escapeJs($_divId); ?>').fire('category:beforeLoad', {treeLoader:treeLoader}); treeLoader.baseParams.id = node.attributes.id; }); - tree<?php echo $block->escapeHtml($block->getId()) ?> = new Ext.tree.TreePanel.Enhanced('<?php echo $block->escapeHtml($_divId) ?>', { + tree<?php echo $block->escapeJs($block->getId()) ?> = new Ext.tree.TreePanel.Enhanced('<?php echo $block->escapeJs($_divId) ?>', { animate: false, loader: categoryLoader, enableDD: false, containerScroll: true, - rootVisible: '<?php echo $block->escapeHtml($block->getRoot()->getIsVisible()) ?>', + rootVisible: '<?php echo $block->escapeJs($block->getRoot()->getIsVisible()) ?>', useAjax: true, currentNodeId: <?php echo (int) $block->getCategoryId() ?>, addNodeTo: false }); if (useMassaction) { - tree<?php echo $block->escapeHtml($block->getId()) ?>.on('check', function(node) { - $('<?php echo $block->escapeHtml($_divId); ?>').fire('node:changed', {node:node}); - }, tree<?php echo $block->escapeHtml($block->getId()) ?>); + tree<?php echo $block->escapeJs($block->getId()) ?>.on('check', function(node) { + $('<?php echo $block->escapeJs($_divId); ?>').fire('node:changed', {node:node}); + }, tree<?php echo $block->escapeJs($block->getId()) ?>); } // set the root node @@ -179,7 +179,7 @@ jQuery(function() category_id: <?php echo (int) $block->getCategoryId() ?> }; - tree<?php echo $block->escapeHtml($block->getId()) ?>.loadTree({parameters:parameters, data:<?php /* @noEscape */ echo $block->getTreeJson() ?>},true); + tree<?php echo $block->escapeJs($block->getId()) ?>.loadTree({parameters:parameters, data:<?php /* @noEscape */ echo $block->getTreeJson() ?>},true); }); diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index fac1674c3e5..612053a6ab0 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -39,27 +39,26 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</div>'+ '<div class="fieldset-wrapper-content">'+ <?php foreach ($block->getDisplayOnContainers() as $container): ?> - <?php $containerName = $block->escapeHtmlAttr($container['name']) ?> - '<div class="no-display <?php echo $block->escapeHtmlAttr($container['code']) ?> group_container" id="<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>]" />'+ - '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][page_id]" value="<%- data.page_id %>" />'+ - '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][layout_handle]" value="<?php echo $block->escapeHtmlAttr($container['layout_handle']) ?>" />'+ + '<div class="no-display <?php echo $block->escapeJs($container['code']) ?> group_container" id="<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>">'+ + '<input disabled="disabled" type="hidden" class="container_name" name="__[container_name]" value="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>]" />'+ + '<input disabled="disabled" type="hidden" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][page_id]" value="<%- data.page_id %>" />'+ + '<input disabled="disabled" type="hidden" class="layout_handle_pattern" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][layout_handle]" value="<?php echo $block->escapeJs($container['layout_handle']) ?>" />'+ '<table class="data-table">'+ '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeHtml(__('%1', $container['label'])) ?></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('%1', $container['label'])) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ '<td>'+ - '<input disabled="disabled" type="radio" class="radio for_all" id="all_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][for]" value="all" onclick="WidgetInstance.togglePageGroupChooser(this)" checked="checked" /> '+ - '<label for="all_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>"><?php echo $block->escapeHtml(__('All')) ?></label><br />'+ - '<input disabled="disabled" type="radio" class="radio for_specific" id="specific_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][for]" value="specific" onclick="WidgetInstance.togglePageGroupChooser(this)" /> '+ - '<label for="specific_<?php /* @noEscape */ echo $containerName ?>_<%- data.id %>"><?php echo $block->escapeHtml(__('Specific %1', $container['label'])) ?></label>'+ + '<input disabled="disabled" type="radio" class="radio for_all" id="all_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][for]" value="all" onclick="WidgetInstance.togglePageGroupChooser(this)" checked="checked" /> '+ + '<label for="all_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>"><?php echo $block->escapeJs(__('All')) ?></label><br />'+ + '<input disabled="disabled" type="radio" class="radio for_specific" id="specific_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][for]" value="specific" onclick="WidgetInstance.togglePageGroupChooser(this)" /> '+ + '<label for="specific_<?php echo $block->escapeJs($container['name']) ?>_<%- data.id %>"><?php echo $block->escapeJs(__('Specific %1', $container['label'])) ?></label>'+ '</td>'+ '<td>'+ '<div class="block_reference_container">'+ @@ -74,16 +73,16 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</tr>'+ '</tbody>'+ '</table>'+ - '<div class="no-display chooser_container" id="<?php /* @noEscape */ echo $containerName ?>_ids_<%- data.id %>">'+ - '<input disabled="disabled" type="hidden" class="is_anchor_only" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][is_anchor_only]" value="<?php echo $block->escapeHtmlAttr($container['is_anchor_only']) ?>" />'+ - '<input disabled="disabled" type="hidden" class="product_type_id" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][product_type_id]" value="<?php echo $block->escapeHtmlAttr($container['product_type_id']) ?>" />'+ + '<div class="no-display chooser_container" id="<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>">'+ + '<input disabled="disabled" type="hidden" class="is_anchor_only" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][is_anchor_only]" value="<?php echo $block->escapeJs($container['is_anchor_only']) ?>" />'+ + '<input disabled="disabled" type="hidden" class="product_type_id" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][product_type_id]" value="<?php echo $block->escapeJs($container['product_type_id']) ?>" />'+ '<p>' + - '<input disabled="disabled" type="text" class="input-text entities" name="widget_instance[<%- data.id %>][<?php /* @noEscape */ echo $containerName ?>][entities]" value="<%- data.<?php /* @noEscape */ echo $containerName ?>_entities %>" readonly="readonly" /> ' + - '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php echo $block->escapeHtml($container['code']) ?>\', \'<?php /* @noEscape */ echo $containerName ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeHtmlAttr(__('Open Chooser')) ?>">' + - '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_chooser_trigger.gif')) ?>" alt="<?php echo $block->escapeHtmlAttr(__('Open Chooser')); ?>" />' + + '<input disabled="disabled" type="text" class="input-text entities" name="widget_instance[<%- data.id %>][<?php echo $block->escapeJs($container['name']) ?>][entities]" value="<%- data.<?php echo $block->escapeJs($container['name']) ?>_entities %>" readonly="readonly" /> ' + + '<a class="widget-option-chooser" href="javascript:void(0)" onclick="WidgetInstance.displayEntityChooser(\'<?php echo $block->escapeJs($container['code']) ?>\', \'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Open Chooser')) ?>">' + + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_chooser_trigger.gif')) ?>" alt="<?php echo $block->escapeJs(__('Open Chooser')); ?>" />' + '</a> ' + - '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeHtml($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeHtmlAttr(__('Apply')); ?>">' + - '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>" alt="<?php echo $block->escapeHtmlAttr(__('Apply')); ?>" />' + + '<a href="javascript:void(0)" onclick="WidgetInstance.hideEntityChooser(\'<?php echo $block->escapeJs($container['name']) ?>_ids_<%- data.id %>\')" title="<?php echo $block->escapeJs(__('Apply')); ?>">' + + '<img src="<?php echo $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>" alt="<?php echo $block->escapeJs(__('Apply')); ?>" />' + '</a>' + '</p>'+ '<div class="chooser"></div>'+ @@ -99,8 +98,8 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '<th> </th>'+ '</tr>'+ '</thead>'+ @@ -129,14 +128,14 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeHtml(__('Page')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php /* @noEscape */ echo $block->getLayoutsChooser() ?></td>'+ + '<td><?php echo $block->escapeJs($block->getLayoutsChooser()) ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ @@ -160,14 +159,14 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '<col width="200" />'+ '<thead>'+ '<tr>'+ - '<th><label><?php echo $block->escapeHtml(__('Page')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Container')) ?> <span class="required">*</span></label></th>'+ - '<th><label><?php echo $block->escapeHtml(__('Template')) ?></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Page')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Container')) ?> <span class="required">*</span></label></th>'+ + '<th><label><?php echo $block->escapeJs(__('Template')) ?></label></th>'+ '</tr>'+ '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php /* @noEscape */ echo $block->getPageLayoutsPageChooser() ?></td>'+ + '<td><?php echo $block->escapeJs($block->getPageLayoutsPageChooser()) ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ -- GitLab From a05441eaa2fa2176206b658503e2e1ae26d81c40 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 13:00:40 -0500 Subject: [PATCH 336/838] MAGETWO-55926: Eliminate @escapeNotVerified in Cms Module Applying escape functions in templates --- .../Cms/view/adminhtml/templates/browser/content/uploader.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1272936ec7a..8d9aea7bb20 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 @@ -39,7 +39,7 @@ require([ }, sequentialUploads: true, acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - maxFileSize: <?php echo $block->escapeHtml($block->getFileSizeService()->getMaxFileSize()) ?> , + maxFileSize: <?php echo $block->escapeJs($block->getFileSizeService()->getMaxFileSize()) ?>, add: function (e, data) { var progressTmpl = mageTemplate('#<?php echo $block->getHtmlId(); ?>-template'), fileSize, -- GitLab From de46d5a20cba088bfa6663e0c65cb83aa489da33 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 13:55:59 -0500 Subject: [PATCH 337/838] MAGETWO-56364: Prepare test scenarios in Widget Module Applying escape functions in templates --- .../view/adminhtml/templates/instance/edit/layout.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml index 612053a6ab0..62d92ac38ae 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/instance/edit/layout.phtml @@ -135,7 +135,7 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php echo $block->escapeJs($block->getLayoutsChooser()) ?></td>'+ + '<td><?php /* @noEscape */ echo $block->getLayoutsChooser() ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ @@ -166,7 +166,7 @@ var pageGroupTemplate = '<div class="fieldset-wrapper page_group_container" id=" '</thead>'+ '<tbody>'+ '<tr>'+ - '<td><?php echo $block->escapeJs($block->getPageLayoutsPageChooser()) ?></td>'+ + '<td><?php /* @noEscape */ echo $block->getPageLayoutsPageChooser() ?></td>'+ '<td>'+ '<div class="block_reference_container">'+ '<div class="block_reference"></div>'+ -- GitLab From 6a5eb1b2b1aa9fb621b510fa9238763c51e3ca66 Mon Sep 17 00:00:00 2001 From: cspruiell <cspruiell@magento.com> Date: Tue, 9 Aug 2016 17:26:28 -0500 Subject: [PATCH 338/838] MAGETWO-52571: [Github][PR] Add HttpInterface methods and add up-casts for type safety #3746 - suppress coupling warning until refactoring can be performed --- lib/internal/Magento/Framework/View/Result/Layout.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Result/Layout.php b/lib/internal/Magento/Framework/View/Result/Layout.php index a71f5402f89..7bff972271c 100644 --- a/lib/internal/Magento/Framework/View/Result/Layout.php +++ b/lib/internal/Magento/Framework/View/Result/Layout.php @@ -16,6 +16,8 @@ use Magento\Framework\View; * A generic layout response can be used for rendering any kind of layout * So it comprises a response body from the layout elements it has and sets it to the HTTP response * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * * @api */ class Layout extends AbstractResult @@ -160,10 +162,10 @@ class Layout extends AbstractResult { \Magento\Framework\Profiler::start('LAYOUT'); \Magento\Framework\Profiler::start('layout_render'); - + $this->eventManager->dispatch('layout_render_before'); $this->eventManager->dispatch('layout_render_before_' . $this->request->getFullActionName()); - + $this->applyHttpHeaders($httpResponse); $this->render($httpResponse); -- GitLab From d9b8fdd93281fb5b2f90ea4cb23eeb3eef246a8f Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 14:47:10 -0500 Subject: [PATCH 339/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module Applying escape functions in templates --- .../Test/Unit/Helper/Catalog/Product/ConfigurationTest.php | 2 +- .../Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php | 2 +- .../Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php b/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php index d87b6b9a3c5..0919e95a9a0 100644 --- a/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Helper/Catalog/Product/ConfigurationTest.php @@ -260,7 +260,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase [ 'label' => 'title', 'value' => ['1 x name <span class="price">$15.00</span>'], - 'html_value' => true, + 'has_html' => true, ], ['label' => 'title', 'value' => 'value'], ], diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php index 4d69f176fcf..07bb2e7708d 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php @@ -110,7 +110,7 @@ class Options extends \Magento\Wishlist\Block\AbstractBlock $option['value'] = nl2br(implode("\n", $option['value'])); } - if (!(array_key_exists('html_value', $option) && $option['html_value'] === true)) { + if (!(array_key_exists('has_html', $option) && $option['has_html'] === true)) { $option['value'] = $this->escapeHtml($option['value']); } $options[$index]['value'] = $option['value']; diff --git a/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php b/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php index 435448c92b8..37d44e0e047 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php @@ -122,7 +122,7 @@ class OptionsTest extends \PHPUnit_Framework_TestCase [ 'label' => 'title', 'value' => ['1 x name <span class="price">$15.00</span>'], - 'html_value' => true, + 'has_html' => true, ], ['label' => 'title', 'value' => 'value'], ['label' => 'title', 'value' => ['value']], @@ -132,7 +132,7 @@ class OptionsTest extends \PHPUnit_Framework_TestCase [ 'label' => 'title', 'value' => '1 x name <span class="price">$15.00</span>', - 'html_value' => true, + 'has_html' => true, ], ['label' => 'title', 'value' => 'value'], ['label' => 'title', 'value' => 'value'], -- GitLab From 79342d7bcec793e64e14ca943371babe6b8ed9a3 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 14:50:42 -0500 Subject: [PATCH 340/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module Applying escape functions in templates --- .../Magento/Bundle/Helper/Catalog/Product/Configuration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php b/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php index 91a3ec60808..8305bb0137e 100644 --- a/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php +++ b/app/code/Magento/Bundle/Helper/Catalog/Product/Configuration.php @@ -142,7 +142,7 @@ class Configuration extends AbstractHelper implements ConfigurationInterface . $this->pricingHelper->currency( $this->getSelectionFinalPrice($item, $bundleSelection) ); - $option['html_value'] = true; + $option['has_html'] = true; } } -- GitLab From 21add994a37875f3fe0f19a493e5f6b003520c13 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 12 Aug 2016 15:58:42 -0500 Subject: [PATCH 341/838] MAGETWO-55920: Eliminate @escapeNotVerified in Customer Module --- .../Magento/Customer/view/frontend/templates/address/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index f4075b8516d..f9bdeba5036 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -123,7 +123,7 @@ <div class="control"> <select id="region_id" name="region_id" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" - class="validate-select" <?php echo !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : ''; ?>> + class="validate-select" <?php /* @noEscape */ echo !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : ''; ?>> <option value=""><?php /* @escapeNotVerified */ echo __('Please select a region, state or province.') ?></option> </select> <input type="text" -- GitLab From 451634ad39274fc82b477eb5edbee1c2b9c8cc21 Mon Sep 17 00:00:00 2001 From: Mykola Palamar <mpalamar@magento.com> Date: Fri, 5 Aug 2016 16:49:23 +0300 Subject: [PATCH 342/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 --- .../Product/Form/Modifier/Eav.php | 41 ++++++++++++++++++- .../Magento/Eav/Model/Entity/Attribute.php | 9 ++++ .../Attribute/Backend/SelectBackend.php | 22 ++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index edab28873b5..83d2f007031 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -522,6 +522,45 @@ class Eav extends AbstractModifier return $this->prevSetAttributes; } + /** + * Check is product already exists or we trying to create one + * + * @return bool + */ + private function isProductExists() + { + return (bool) $this->locator->getProduct()->getId(); + } + + /** + * Check is product has some value for attribute + * + * @param ProductAttributeInterface $attribute + * @return bool + */ + private function isProductHasValueForAttribute(ProductAttributeInterface $attribute) + { + return (bool)($this->locator->getProduct()->getCustomAttribute($attribute->getAttributeCode()) !== null) + && $this->locator->getProduct()->getCustomAttribute($attribute->getAttributeCode())->getValue(); + } + + /** + * Check should we display default values for attribute or not + * + * @param ProductAttributeInterface $attribute + * @return bool + */ + private function isShowDefaultValue(ProductAttributeInterface $attribute) + { + if (!$this->isProductExists()) { + return true; + } elseif ($attribute->getIsRequired() && !$this->isProductHasValueForAttribute($attribute)) { + return true; + } + + return false; + } + /** * Initial meta setup * @@ -543,7 +582,7 @@ class Eav extends AbstractModifier 'visible' => $attribute->getIsVisible(), 'required' => $attribute->getIsRequired(), 'notice' => $attribute->getNote(), - 'default' => $attribute->getDefaultValue(), + 'default' => $this->isShowDefaultValue($attribute) ? $attribute->getDefaultValue() : null, 'label' => $attribute->getDefaultFrontendLabel(), 'code' => $attribute->getAttributeCode(), 'source' => $groupCode, diff --git a/app/code/Magento/Eav/Model/Entity/Attribute.php b/app/code/Magento/Eav/Model/Entity/Attribute.php index 528dee5f239..79b1089538e 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute.php @@ -167,6 +167,15 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute im break; } + // we should override default behaviour of Magento\Framework\Exception\LocalizedException\AbstractBackend + // but can't do this in abstract model and can't update DB records because of backward compatibility + if ($this->getFrontendInput() == 'select' + && !$this->getIsRequired() + && !$this->getBackendModel() + ) { + return \Magento\Eav\Model\Entity\Attribute\Backend\SelectBackend::class; + } + return parent::_getDefaultBackendModel(); } diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php b/app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php new file mode 100644 index 00000000000..f6fb9fb1b76 --- /dev/null +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Eav\Model\Entity\Attribute\Backend; + +/** + * Entity/Attribute/Model - attribute backend default + * + * @author Magento Core Team <core@magentocommerce.com> + */ +class SelectBackend extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend +{ + + public function beforeSave($object) + { + return $this; + + } +} + -- GitLab From 8a462ba30e674315cd0efe7b7a5a03e2f31bb959 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 15 Aug 2016 11:03:13 +0300 Subject: [PATCH 343/838] MAGETWO-56702: Refactor plugins --- .../Model/Category/Plugin/Category/Remove.php | 41 +++++--- .../Category/Plugin/Category/RemoveTest.php | 98 +++++++++++++++++++ 2 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php index 91bf053304c..1a81c73c157 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php @@ -23,6 +23,9 @@ class Remove /** @var ChildrenCategoriesProvider */ protected $childrenCategoriesProvider; + /** @var array */ + private $categoryIds; + /** * @param UrlPersistInterface $urlPersist * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator @@ -38,25 +41,41 @@ class Remove $this->childrenCategoriesProvider = $childrenCategoriesProvider; } + /** + * Save category ids before delete + * + * @param \Magento\Catalog\Model\ResourceModel\Category $subject + * @param \Magento\Framework\DataObject|int|string $object + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeDelete(\Magento\Catalog\Model\ResourceModel\Category $subject, $object) + { + if ($object instanceof CategoryInterface) { + $this->categoryIds = $this->childrenCategoriesProvider->getChildrenIds($object, true); + $this->categoryIds[] = $object->getId(); + } + return [$object]; + } + /** * Remove product urls from storage * * @param \Magento\Catalog\Model\ResourceModel\Category $subject - * @param callable $proceed - * @param CategoryInterface $category - * @return mixed + * @param \Magento\Catalog\Model\ResourceModel\Category $result + * @param \Magento\Framework\DataObject|int|string $object + * @return \Magento\Catalog\Model\ResourceModel\Category * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDelete( + public function afterDelete( \Magento\Catalog\Model\ResourceModel\Category $subject, - \Closure $proceed, - CategoryInterface $category + \Magento\Catalog\Model\ResourceModel\Category $result, + $object ) { - $categoryIds = $this->childrenCategoriesProvider->getChildrenIds($category, true); - $categoryIds[] = $category->getId(); - $result = $proceed($category); - foreach ($categoryIds as $categoryId) { - $this->deleteRewritesForCategory($categoryId); + if ($object instanceof CategoryInterface) { + foreach ($this->categoryIds as $categoryId) { + $this->deleteRewritesForCategory($categoryId); + } } return $result; } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php new file mode 100644 index 00000000000..8ea717a05b8 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php @@ -0,0 +1,98 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Category; + +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Remove; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; +use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; +use Magento\Catalog\Model\Category; + +class RemoveTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var UrlPersistInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $urlPersistMock; + + /** + * @var ChildrenCategoriesProvider|\PHPUnit_Framework_MockObject_MockObject + */ + private $childrenCategoriesProviderMock; + + /** + * @var ResourceCategory|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectMock; + + /** + * @var Category|\PHPUnit_Framework_MockObject_MockObject + */ + private $objectMock; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->urlPersistMock = $this->getMockBuilder(UrlPersistInterface::class) + ->getMockForAbstractClass(); + $this->childrenCategoriesProviderMock = $this->getMockBuilder(ChildrenCategoriesProvider::class) + ->getMock(); + $this->subjectMock = $this->getMockBuilder(ResourceCategory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->objectMock = $this->getMockBuilder(Category::class) + ->disableOriginalConstructor() + ->getMock(); + } + + public function testBeforeDelete() + { + $expectedResult = [$this->objectMock]; + $plugin = $this->objectManager->getObject( + Remove::class, + [ + 'urlPersist' => $this->urlPersistMock, + 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock + ] + ); + $this->childrenCategoriesProviderMock->expects($this->once()) + ->method('getChildrenIds') + ->with($this->objectMock, true) + ->willReturn([]); + $this->objectMock->expects($this->once()) + ->method('getId') + ->willReturn(1); + $this->assertEquals( + $expectedResult, + $plugin->beforeDelete($this->subjectMock, $this->objectMock) + ); + } + + public function testAfterDelete() + { + $categoryIds = [1]; + $this->urlPersistMock->expects($this->exactly(2)) + ->method('deleteByData'); + $plugin = $this->objectManager->getObject( + Remove::class, + [ + 'urlPersist' => $this->urlPersistMock, + 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock, + 'categoryIds' => $categoryIds + ] + ); + $this->assertEquals( + $this->subjectMock, + $plugin->afterDelete($this->subjectMock, $this->subjectMock, $this->objectMock) + ); + } +} -- GitLab From 0189202bd0ed2857d5031777f4989abb3ff5a5eb Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Mon, 15 Aug 2016 11:18:07 +0300 Subject: [PATCH 344/838] MAGETWO-56488: Introduce and implement ShipmentTrackCreationInterface --- .../Magento/Sales/Model/Order/Shipment/TrackCreation.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index 80129fae628..0618ae0f6ab 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -23,11 +23,6 @@ class TrackCreation implements ShipmentTrackCreationInterface */ private $qty; - /** - * @var int - */ - private $orderId; - /** * @var string */ -- GitLab From 1e035d94e475f48a51df2f47cdeddbcd60427250 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 15 Aug 2016 12:20:42 +0300 Subject: [PATCH 345/838] MAGETWO-56702: Refactor plugins --- .../Model/Category/Plugin/Category/Move.php | 18 +-- .../Category/Plugin/Category/MoveTest.php | 105 ++++++++++++++++++ 2 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php index 1477a106554..7a4c94dde0c 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php @@ -14,6 +14,11 @@ class Move /** @var CategoryUrlPathGenerator */ protected $categoryUrlPathGenerator; + /** + * @var ChildrenCategoriesProvider + */ + private $childrenCategoriesProvider; + /** * @param CategoryUrlPathGenerator $categoryUrlPathGenerator * @param ChildrenCategoriesProvider $childrenCategoriesProvider @@ -28,21 +33,20 @@ class Move /** * @param \Magento\Catalog\Model\ResourceModel\Category $subject - * @param callable $proceed + * @param \Magento\Catalog\Model\ResourceModel\Category $result * @param Category $category * @param Category $newParent * @param null|int $afterCategoryId - * @return callable + * @return \Magento\Catalog\Model\ResourceModel\Category * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundChangeParent( + public function afterChangeParent( \Magento\Catalog\Model\ResourceModel\Category $subject, - \Closure $proceed, - $category, - $newParent, + \Magento\Catalog\Model\ResourceModel\Category $result, + Category $category, + Category $newParent, $afterCategoryId ) { - $result = $proceed($category, $newParent, $afterCategoryId); $category->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); $category->getResource()->saveAttribute($category, 'url_path'); $this->updateUrlPathForChildren($category); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php new file mode 100644 index 00000000000..a3a09e9c42f --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Category; + +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Move; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; +use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; +use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; +use Magento\Catalog\Model\Category; + +class MoveTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var ChildrenCategoriesProvider|\PHPUnit_Framework_MockObject_MockObject + */ + private $childrenCategoriesProviderMock; + + /** + * @var CategoryUrlPathGenerator|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryUrlPathGeneratorMock; + + /** + * @var ResourceCategory|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectMock; + + /** + * @var Category|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryMock; + + /** + * @var Move + */ + private $plugin; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->categoryUrlPathGeneratorMock = $this->getMockBuilder(CategoryUrlPathGenerator::class) + ->disableOriginalConstructor() + ->setMethods(['getUrlPath']) + ->getMock(); + $this->childrenCategoriesProviderMock = $this->getMockBuilder(ChildrenCategoriesProvider::class) + ->disableOriginalConstructor() + ->setMethods(['getChildren']) + ->getMock(); + $this->subjectMock = $this->getMockBuilder(ResourceCategory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->categoryMock = $this->getMockBuilder(Category::class) + ->disableOriginalConstructor() + ->setMethods(['getResource', 'setUrlPath']) + ->getMock(); + $this->plugin = $this->objectManager->getObject( + Move::class, + [ + 'categoryUrlPathGenerator' => $this->categoryUrlPathGeneratorMock, + 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock + ] + ); + } + + public function testAfterChangeParent() + { + $urlPath = 'test/path'; + $this->categoryMock->expects($this->once()) + ->method('getResource') + ->willReturn($this->subjectMock); + $this->childrenCategoriesProviderMock->expects($this->once()) + ->method('getChildren') + ->with($this->categoryMock, true) + ->willReturn([]); + $this->categoryUrlPathGeneratorMock->expects($this->once()) + ->method('getUrlPath') + ->with($this->categoryMock) + ->willReturn($urlPath); + $this->categoryMock->expects($this->once()) + ->method('getResource') + ->willReturn($this->subjectMock); + $this->categoryMock->expects($this->once()) + ->method('setUrlPath') + ->with($urlPath); + $this->assertEquals( + $this->subjectMock, + $this->plugin->afterChangeParent( + $this->subjectMock, + $this->subjectMock, + $this->categoryMock, + $this->categoryMock, + null + ) + ); + } +} -- GitLab From cc9f0a6886d4c0977a91e66bb89740168b816cd4 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 15 Aug 2016 12:37:22 +0300 Subject: [PATCH 346/838] MAGETWO-46317: Support Multiple Updates on the WebSetup --- setup/config/states.extensionManager.config.php | 2 +- setup/view/magento/setup/extension-grid.phtml | 8 ++++---- setup/view/magento/setup/install-extension-grid.phtml | 4 ++-- setup/view/magento/setup/module-grid.phtml | 6 +++--- .../view/magento/setup/readiness-check/progress.phtml | 10 +++++----- setup/view/magento/setup/update-extension-grid.phtml | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/setup/config/states.extensionManager.config.php b/setup/config/states.extensionManager.config.php index 5c70105c721..e46b83c50c3 100644 --- a/setup/config/states.extensionManager.config.php +++ b/setup/config/states.extensionManager.config.php @@ -65,7 +65,7 @@ return [ 'templateUrl' => "$base/start-updater", 'controller' => 'startUpdaterController', 'title' => "Component \n Install", - 'header' => 'Step 3: Component Install', + 'header' => 'Step 3: Install', 'nav' => true, 'order' => 6, 'type' => 'install', diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index e309f020518..2ec0fe31bc5 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -31,7 +31,7 @@ </li> <li class="item col-m-4"> <div class="item-number">{{countOfInstall}}</div> - <div class="item-title">Products<br />Ready to Install</div> + <div class="item-title">Extensions<br />Ready to Install</div> <div class="item-install"> <button ui-sref="root.install" href="#install-extension-grid" ng-class="{'disabled' : !enabledInstall, 'goInstall' : enabledInstall}" @@ -77,8 +77,8 @@ <div class="admin__data-grid-header"> <div class="admin__data-grid-header-row row row-gutter"> <div class="col-xs-3 module-summary"> - <span class="module-summary-title">Installed Products</span> - <span class="module-summary-count">{{total}} products</span> + <span class="module-summary-title">Installed Extensions</span> + <span class="module-summary-count">{{total}} extensions</span> </div> <div class="col-xs-9 admin__data-grid-pager-wrap" ng-include="'<?php echo $this->basePath();?>/pub/magento/setup/view/pagination.html'"> @@ -93,7 +93,7 @@ ng-class="{'_ascend' : predicate === 'name' && !reverse, '_descend' : predicate === 'name' && reverse}" class="data-grid-th _sortable"> - <span>Product Name</span> + <span>Extension Name</span> </th> <th ng-click="order('type')" ng-class="{'_ascend' : predicate === 'type' && !reverse, diff --git a/setup/view/magento/setup/install-extension-grid.phtml b/setup/view/magento/setup/install-extension-grid.phtml index ec8ffabb449..9ffe49719c1 100644 --- a/setup/view/magento/setup/install-extension-grid.phtml +++ b/setup/view/magento/setup/install-extension-grid.phtml @@ -19,7 +19,7 @@ <div class="col-xs-3"> <button type="button" class="btn" ng-click="installAll()">Install</button> <div class="admin__control-support-text"> - <span>{{total}}</span> products + <span>{{total}}</span> extensions </div> </div> <div class="col-xs-9 admin__data-grid-pager-wrap" @@ -65,7 +65,7 @@ </th> <th ng-click="order('name')" ng-class="{'_ascend' : predicate === 'name' && !reverse,'_descend' : predicate === 'name' && reverse}" class="data-grid-th _sortable"> - <span>Product Name</span> + <span>Extension Name</span> </th> <th ng-click="order('type')" ng-class="{'_ascend' : predicate === 'type' && !reverse,'_descend' : predicate === 'type' && reverse}" class="data-grid-th _sortable"> diff --git a/setup/view/magento/setup/module-grid.phtml b/setup/view/magento/setup/module-grid.phtml index f6b3e6ae5d7..84b0c07b795 100644 --- a/setup/view/magento/setup/module-grid.phtml +++ b/setup/view/magento/setup/module-grid.phtml @@ -82,10 +82,10 @@ </div> <div class="product-modules-block" ng-show="item.requiredBy.length > 0 && showDependencies"> <div class="product-modules-title"> - Products currently using module + Packages currently using module </div> <div class="product-modules-descriprion"> - Product Name + Module Name </div> <ul class="product-modules-list"> <li ng-repeat="product in item.requiredBy"> @@ -106,7 +106,7 @@ </div> <div class="product-modules-descriprion"> - Product Type + Module Type </div> <ul class="product-modules-list"> <li ng-repeat="product in item.requiredBy"> diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 24d5034d999..2a3b87d03bc 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -557,14 +557,14 @@ </header> <div class="modal-content" data-role="content"> <div class="delete-modal-wrap"> - <h3>Remove Product</h3> + <h3>Remove Extension</h3> <p>Are you sure you want to remove “{{extensionToRemove}}†from the list?</p> <p> - Please be aware that removing this product will remove it from the current - update wizard flow. You can update this product at a later time by selecting - the product in the update grid. + Please be aware that removing this extension will remove it from the current + update wizard flow. You can update this extension at a later time by selecting + the extension in the update grid. </p> <div class="actions"> <button ng-click="removeExtension(extensionToRemove)" class="btn btn-large btn-prime"> @@ -579,4 +579,4 @@ </div> </aside> </div> -</script> \ No newline at end of file +</script> diff --git a/setup/view/magento/setup/update-extension-grid.phtml b/setup/view/magento/setup/update-extension-grid.phtml index 6ee2784079e..7cf30c51784 100644 --- a/setup/view/magento/setup/update-extension-grid.phtml +++ b/setup/view/magento/setup/update-extension-grid.phtml @@ -19,7 +19,7 @@ <div class="col-xs-3"> <button type="button" class="btn" ng-click="updateAll()">Update</button> <div class="admin__control-support-text"> - <span>{{total}}</span> products + <span>{{total}}</span> extensions </div> </div> <div class="col-xs-9 admin__data-grid-pager-wrap" @@ -66,7 +66,7 @@ </th> <th ng-click="order('name')" ng-class="{'_ascend' : predicate === 'name' && !reverse,'_descend' : predicate === 'name' && reverse}" class="data-grid-th _sortable"> - <span>Product Name</span> + <span>Extension Name</span> </th> <th ng-click="order('type')" ng-class="{'_ascend' : predicate === 'type' && !reverse,'_descend' : predicate === 'type' && reverse}" class="data-grid-th _sortable"> -- GitLab From 386db3a9a0e9b11e67db5e20e94191086f499e41 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 15 Aug 2016 12:59:46 +0300 Subject: [PATCH 347/838] MAGETWO-46317: Support Multiple Updates on the WebSetup --- setup/view/magento/setup/module-grid.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/view/magento/setup/module-grid.phtml b/setup/view/magento/setup/module-grid.phtml index 84b0c07b795..e879d8735cf 100644 --- a/setup/view/magento/setup/module-grid.phtml +++ b/setup/view/magento/setup/module-grid.phtml @@ -106,7 +106,7 @@ </div> <div class="product-modules-descriprion"> - Module Type + Package Type </div> <ul class="product-modules-list"> <li ng-repeat="product in item.requiredBy"> -- GitLab From 3278cd79252c43d24a1ecf5e511e0665fc30bf1a Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Mon, 15 Aug 2016 13:15:55 +0300 Subject: [PATCH 348/838] MAGETWO-53135: [GITHUB] Prices of related products on PDP changes according to product custom options. #4588 --- .../Catalog/view/frontend/templates/product/view/form.phtml | 4 +++- .../view/frontend/templates/product/view/options.phtml | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index f6dd2a0033f..f23544a7734 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -42,7 +42,9 @@ 'jquery', 'Magento_Catalog/js/price-box' ], function($){ - var priceBoxes = $('[data-role=priceBox]'); + var dataPriceBoxSelector = '[data-role=priceBox]', + dataProductIdSelector = '[data-product-id=<?php echo $block->escapeHtml($_product->getId());?>]', + priceBoxes = $(dataPriceBoxSelector + dataProductIdSelector); priceBoxes = priceBoxes.filter(function(index, elem){ return !$(elem).find('.price-from').length; diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml index 97f844067f0..ec8f3c86483 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml @@ -10,6 +10,7 @@ ?> <?php $_options = $block->decorateArray($block->getOptions()) ?> +<?php $_productId = $block->getProduct()->getId() ?> <?php if (count($_options)):?> <script type="text/x-magento-init"> { @@ -17,7 +18,7 @@ "priceOptions": { "optionConfig": <?php /* @escapeNotVerified */ echo $block->getJsonConfig()?>, "controlContainer": ".field", - "priceHolderSelector": "[data-role=priceBox]" + "priceHolderSelector": "[data-product-id='<?php echo $_productId?>'][data-role=priceBox]" } } } -- GitLab From 680966e89cd5a1a7a9725e91846e744449c26853 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Mon, 15 Aug 2016 13:18:09 +0300 Subject: [PATCH 349/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Method/Checks/SpecificationPlugin.php | 18 +- .../Method/Checks/SpecificationPluginTest.php | 227 ++++++++++-------- 2 files changed, 135 insertions(+), 110 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php b/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php index a171cd5628f..2ae65a8a70c 100644 --- a/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php +++ b/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php @@ -16,44 +16,46 @@ class SpecificationPlugin /** * @var AgreementFactory */ - protected $_agreementFactory; + private $agreementFactory; /** * @param AgreementFactory $agreementFactory */ public function __construct(AgreementFactory $agreementFactory) { - $this->_agreementFactory = $agreementFactory; + $this->agreementFactory = $agreementFactory; } /** * Override check for Billing Agreements * * @param SpecificationInterface $specification - * @param \Closure $proceed + * @param bool $result * @param MethodInterface $paymentMethod * @param Quote $quote * @return bool + * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundIsApplicable( + public function afterIsApplicable( SpecificationInterface $specification, - \Closure $proceed, + $result, MethodInterface $paymentMethod, Quote $quote ) { - $originallyIsApplicable = $proceed($paymentMethod, $quote); - if (!$originallyIsApplicable) { + if (!$result) { return false; } if ($paymentMethod->getCode() == Config::METHOD_BILLING_AGREEMENT) { if ($quote->getCustomerId()) { - $availableBA = $this->_agreementFactory->create()->getAvailableCustomerBillingAgreements( + $availableBA = $this->agreementFactory->create()->getAvailableCustomerBillingAgreements( $quote->getCustomerId() ); + return count($availableBA) > 0; } + return false; } diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php index eb8eb1091b0..fcab94d2d22 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php @@ -3,155 +3,178 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Paypal\Test\Unit\Model\Method\Checks; +use Magento\Paypal\Model\Method\Checks\SpecificationPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Paypal\Model\Billing\AgreementFactory as BillingAgreementFactory; +use Magento\Payment\Model\Checks\SpecificationInterface; use Magento\Payment\Model\MethodInterface; -use Magento\Paypal\Model\Billing\AgreementFactory; use Magento\Quote\Model\Quote; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Paypal\Model\ResourceModel\Billing\Agreement\Collection as BillingAgreementCollection; +use Magento\Paypal\Model\Billing\Agreement as BillingAgreement; class SpecificationPluginTest extends \PHPUnit_Framework_TestCase { - /** @var SpecificationPlugin */ - protected $model; + /** + * @var SpecificationPlugin + */ + private $plugin; + + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; - /** @var AgreementFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $agreementFactory; + /** + * @var BillingAgreementFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $billingAgreementFactoryMock; + + /** + * @var SpecificationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $specificationMock; + + /** + * @var MethodInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $paymentMethodMock; + + /** + * @var Quote|\PHPUnit_Framework_MockObject_MockObject + */ + private $quoteMock; + + /** + * @var BillingAgreementCollection|\PHPUnit_Framework_MockObject_MockObject + */ + private $billingAgreementCollectionMock; + + /** + * @var BillingAgreement|\PHPUnit_Framework_MockObject_MockObject + */ + private $billingAgreementMock; protected function setUp() { - $this->agreementFactory = $this->getMockBuilder(\Magento\Paypal\Model\Billing\AgreementFactory::class) + $this->billingAgreementFactoryMock = $this->getMockBuilder(BillingAgreementFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); + $this->specificationMock = $this->getMockBuilder(SpecificationInterface::class) + ->getMockForAbstractClass(); + $this->paymentMethodMock = $this->getMockBuilder(MethodInterface::class) + ->getMockForAbstractClass(); + $this->quoteMock = $this->getMockBuilder(Quote::class) + ->disableOriginalConstructor() + ->setMethods(['getCustomerId']) + ->getMock(); + $this->billingAgreementCollectionMock = $this->getMockBuilder(BillingAgreementCollection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->billingAgreementMock = $this->getMockBuilder(BillingAgreement::class) + ->disableOriginalConstructor() + ->getMock(); - $objectManagerHelper = new ObjectManagerHelper($this); - $this->model = $objectManagerHelper->getObject( - \Magento\Paypal\Model\Method\Checks\SpecificationPlugin::class, + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + SpecificationPlugin::class, [ - 'agreementFactory' => $this->agreementFactory + 'agreementFactory' => $this->billingAgreementFactoryMock ] ); } - public function testAroundIsApplicableNotOriginallyApplicable() + public function testAfterIsApplicableNotOriginallyApplicable() { - $paymentMethod = $this->getPaymentMethod('any'); - $quote = $this->getQuote('any'); - $proceed = $this->getProceedClosure(false, $paymentMethod, $quote); - $this->assertFalse($this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + $this->setExpectations('any', 'any'); + + $this->assertFalse( + $this->plugin->afterIsApplicable( + $this->specificationMock, + false, + $this->paymentMethodMock, + $this->quoteMock + ) + ); } - public function testAroundIsApplicableNotAgreement() + public function testAfterIsApplicableNotAgreement() { - $paymentMethod = $this->getPaymentMethod('not_agreement'); - $quote = $this->getQuote('any'); - $proceed = $this->getProceedClosure(true, $paymentMethod, $quote); - $this->assertTrue($this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + $this->setExpectations('not_agreement', 'any'); + + $this->assertTrue( + $this->plugin->afterIsApplicable( + $this->specificationMock, + true, + $this->paymentMethodMock, + $this->quoteMock + ) + ); } - public function testAroundIsApplicableNoCustomerId() + public function testAfterIsApplicableNoCustomerId() { - $paymentMethod = $this->getPaymentMethod('paypal_billing_agreement'); - $quote = $this->getQuote(null); - $proceed = $this->getProceedClosure(true, $paymentMethod, $quote); - $this->assertFalse($this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); + $this->setExpectations('paypal_billing_agreement', null); + + $this->assertFalse( + $this->plugin->afterIsApplicable( + $this->specificationMock, + true, + $this->paymentMethodMock, + $this->quoteMock + ) + ); } /** * @param int $count - * @dataProvider aroundIsApplicableDataProvider + * @dataProvider afterIsApplicableDataProvider */ - public function testAroundIsApplicable($count) + public function testAfterIsApplicable($count) { - $paymentMethod = $this->getPaymentMethod('paypal_billing_agreement'); - $quote = $this->getQuote(1); - $proceed = $this->getProceedClosure(true, $paymentMethod, $quote); - $agreementCollection = $this->getMock( - \Magento\Paypal\Model\ResourceModel\Billing\Agreement\Collection::class, - [], - [], - '', - false - ); - $agreementCollection->expects($this->once()) - ->method('count') - ->will($this->returnValue($count)); - $agreement = $this->getMock(\Magento\Paypal\Model\Billing\Agreement::class, [], [], '', false); - $agreement->expects($this->once()) + $this->setExpectations('paypal_billing_agreement', 1); + + $this->billingAgreementFactoryMock->expects(static::once()) + ->method('create') + ->willReturn($this->billingAgreementMock); + $this->billingAgreementMock->expects(static::once()) ->method('getAvailableCustomerBillingAgreements') ->with(1) - ->will($this->returnValue($agreementCollection)); - $this->agreementFactory->expects($this->once()) - ->method('create') - ->will($this->returnValue($agreement)); - $this->assertEquals($count > 0, $this->callAroundIsApplicable($proceed, $paymentMethod, $quote)); - } - - public function aroundIsApplicableDataProvider() - { - return [[0], [1], [2]]; - } + ->willReturn($this->billingAgreementCollectionMock); + $this->billingAgreementCollectionMock->expects(static::once()) + ->method('count') + ->willReturn($count); - /** - * @param bool $result - * @param MethodInterface $paymentMethod - * @param Quote $quote - * @return \Closure - */ - private function getProceedClosure($result, MethodInterface $paymentMethod, Quote $quote) - { - $self = $this; - return function ($parameter1, $parameter2) use ($result, $paymentMethod, $quote, $self) { - $self->assertSame($paymentMethod, $parameter1); - $self->assertSame($quote, $parameter2); - return $result; - }; + $this->assertEquals( + $count > 0, + $this->plugin->afterIsApplicable($this->specificationMock, true, $this->paymentMethodMock, $this->quoteMock) + ); } /** - * Get payment method parameter - * - * @param string $code - * @return MethodInterface|\PHPUnit_Framework_MockObject_MockObject + * @return array */ - private function getPaymentMethod($code) + public function afterIsApplicableDataProvider() { - $paymentMethod = $this->getMockForAbstractClass(\Magento\Payment\Model\MethodInterface::class); - $paymentMethod->expects($this->any()) - ->method('getCode') - ->will($this->returnValue($code)); - return $paymentMethod; + return [[0], [1], [2]]; } /** - * Get quote parameter + * Set expectations * + * @param mixed $paymentMethodCode * @param mixed $customerId - * @return Quote|\PHPUnit_Framework_MockObject_MockObject + * @return void */ - private function getQuote($customerId) + private function setExpectations($paymentMethodCode, $customerId) { - $quote = $this->getMock(\Magento\Quote\Model\Quote::class, ['__wakeup'], [], '', false); - $quote->setCustomerId($customerId); - return $quote; - } - - /** - * Call aroundIsApplicable method - * - * @param \Closure $proceed - * @param MethodInterface $paymentMethod - * @param Quote $quote - * @return bool - */ - private function callAroundIsApplicable( - \Closure $proceed, - MethodInterface $paymentMethod, - Quote $quote - ) { - $specification = $this->getMockForAbstractClass(\Magento\Payment\Model\Checks\SpecificationInterface::class); - return $this->model->aroundIsApplicable($specification, $proceed, $paymentMethod, $quote); + $this->paymentMethodMock->expects(static::any()) + ->method('getCode') + ->willReturn($paymentMethodCode); + $this->quoteMock->expects(static::any()) + ->method('getCustomerId') + ->willReturn($customerId); } } -- GitLab From 37d9c1d8de467d1cfbae8d4c0af854fb14736c9a Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Mon, 15 Aug 2016 13:23:13 +0300 Subject: [PATCH 350/838] MAGETWO-55234: Image does not save when edited via right-click and "Insert/Edit Image" --- lib/web/tiny_mce/plugins/advimage/js/image.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/tiny_mce/plugins/advimage/js/image.js b/lib/web/tiny_mce/plugins/advimage/js/image.js index f87c40ff8fc..82180640986 100644 --- a/lib/web/tiny_mce/plugins/advimage/js/image.js +++ b/lib/web/tiny_mce/plugins/advimage/js/image.js @@ -184,7 +184,7 @@ var ImageDialog = { tinyMCEPopup.editor.execCommand('mceRepaint'); tinyMCEPopup.editor.focus(); tinyMCEPopup.close(); - ed.onChange.dispatch(ed); + ed.onChange.dispatch(ed); }, getAttrib : function(e, at) { -- GitLab From 1c5f3802b3c76b93f2c856fdc580e9772be30368 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Mon, 15 Aug 2016 13:51:14 +0300 Subject: [PATCH 351/838] MAGETWO-24139: Resolve TODO's related to Customer Service or create stories --- app/code/Magento/Customer/Model/Address/AbstractAddress.php | 2 +- .../Magento/Eav/Api/Data/AttributeDefaultValueInterface.php | 5 +++-- app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php index 60756fd5660..7b32da94dde 100644 --- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php +++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php @@ -393,7 +393,6 @@ class AbstractAddress extends AbstractExtensibleModel implements AddressModelInt if (!$regionId) { if (is_numeric($region)) { $this->setData('region_id', $region); - //@TODO method unsRegion() is neither defined in abstract model nor in it's children $this->unsRegion(); } else { $regionModel = $this->_createRegionInstance()->loadByCode( @@ -631,6 +630,7 @@ class AbstractAddress extends AbstractExtensibleModel implements AddressModelInt } /** + * Unset Region from address * @return $this */ public function unsRegion() diff --git a/app/code/Magento/Eav/Api/Data/AttributeDefaultValueInterface.php b/app/code/Magento/Eav/Api/Data/AttributeDefaultValueInterface.php index 9fbd6efa97e..e4b33833eb7 100644 --- a/app/code/Magento/Eav/Api/Data/AttributeDefaultValueInterface.php +++ b/app/code/Magento/Eav/Api/Data/AttributeDefaultValueInterface.php @@ -7,10 +7,11 @@ namespace Magento\Eav\Api\Data; /** - * Interface AttributeInterface + * Interface AttributeDefaultValueInterface + * Allows to manage attribute default value through interface * @api + * @package Magento\Eav\Api\Data */ - interface AttributeDefaultValueInterface { const DEFAULT_VALUE = "default_value"; diff --git a/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php b/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php index 5b10eff928e..2e5b5ee6a2e 100644 --- a/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php +++ b/app/code/Magento/Store/Api/StoreWebsiteRelationInterface.php @@ -6,9 +6,11 @@ namespace Magento\Store\Api; /** + * Interface StoreWebsiteRelationInterface + * Provides stores information by website id + * @package Magento\Store\Api * @api */ - interface StoreWebsiteRelationInterface { /** -- GitLab From 697c5ac6a213e73879ffd29c8518332f6b288d1b Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Mon, 15 Aug 2016 14:54:42 +0300 Subject: [PATCH 352/838] MAGETWO-56447: UPS not providing shipping rates for Puerto Rico - Added based on request destination country code for not found countries --- app/code/Magento/Ups/Model/Carrier.php | 4 +- .../Ups/Test/Unit/Model/CarrierTest.php | 47 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php index 17c313af970..ec14e9db90c 100644 --- a/app/code/Magento/Ups/Model/Carrier.php +++ b/app/code/Magento/Ups/Model/Carrier.php @@ -325,13 +325,13 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface $destCountry = self::GUAM_COUNTRY_ID; } - $rowRequest->setDestCountry($this->_countryFactory->create()->load($destCountry)->getData('iso2_code')); + $country = $this->_countryFactory->create()->load($destCountry); + $rowRequest->setDestCountry($country->getData('iso2_code') ?: $destCountry); $rowRequest->setDestRegionCode($request->getDestRegionCode()); if ($request->getDestPostcode()) { $rowRequest->setDestPostal($request->getDestPostcode()); - } else { } $weight = $this->getTotalNumOfBoxes($request->getPackageWeight()); diff --git a/app/code/Magento/Ups/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Ups/Test/Unit/Model/CarrierTest.php index 8f42ea1c804..ea46e534ae8 100644 --- a/app/code/Magento/Ups/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Ups/Test/Unit/Model/CarrierTest.php @@ -7,6 +7,8 @@ namespace Magento\Ups\Test\Unit\Model; use Magento\Quote\Model\Quote\Address\RateRequest; use Magento\Ups\Model\Carrier; +use Magento\Directory\Model\Country; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -57,7 +59,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase protected $countryFactory; /** - * @var \Magento\Directory\Model\Country + * @var Country|MockObject */ protected $country; @@ -309,4 +311,47 @@ class CarrierTest extends \PHPUnit_Framework_TestCase ] ]; } + + /** + * @covers \Magento\Ups\Model\Carrier::setRequest + * @param string $countryCode + * @param string $foundCountryCode + * @dataProvider countryDataProvider + */ + public function testSetRequest($countryCode, $foundCountryCode) + { + /** @var RateRequest $request */ + $request = $this->helper->getObject(RateRequest::class); + $request->setData([ + 'orig_country' => 'USA', + 'orig_region_code' => 'CA', + 'orig_post_code' => 90230, + 'orig_city' => 'Culver City', + 'dest_country_id' => $countryCode, + ]); + + $this->country->expects(static::at(1)) + ->method('load') + ->with($countryCode) + ->willReturnSelf(); + + $this->country->expects(static::any()) + ->method('getData') + ->with('iso2_code') + ->willReturn($foundCountryCode); + + $this->model->setRequest($request); + } + + /** + * Get list of country variations + * @return array + */ + public function countryDataProvider() + { + return [ + ['countryCode' => 'PR', 'foundCountryCode' => null], + ['countryCode' => 'US', 'foundCountryCode' => 'US'], + ]; + } } -- GitLab From 8e4a8d780858f03af1e660558fd5ca612b67d911 Mon Sep 17 00:00:00 2001 From: aakimov <aakimov@magento.com> Date: Mon, 15 Aug 2016 15:05:23 +0300 Subject: [PATCH 353/838] MAGETWO-56824: Notification Messages Area. Refactoring of Notification Message Save Procedure. --- .../Ui/Component/DataProvider/DataProvider.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php b/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php index da7c0c885b1..7ab9c5182ce 100644 --- a/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php +++ b/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php @@ -6,6 +6,8 @@ namespace Magento\AdminNotification\Ui\Component\DataProvider; +use Magento\AdminNotification\Model\ResourceModel\System\Message\Collection\SynchronizedFactory; + /** * Class DataProvider */ @@ -20,7 +22,7 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider * @param string $name * @param string $primaryFieldName * @param string $requestFieldName - * @param \Magento\AdminNotification\Model\ResourceModel\System\Message\CollectionFactory $messageCollectionFactory + * @param SynchronizedFactory $messageCollectionFactory * @param array $meta * @param array $data */ @@ -28,7 +30,7 @@ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider $name, $primaryFieldName, $requestFieldName, - \Magento\AdminNotification\Model\ResourceModel\System\Message\CollectionFactory $messageCollectionFactory, + SynchronizedFactory $messageCollectionFactory, array $meta = [], array $data = [] ) { -- GitLab From 5df995eed0ca8bdd17e8ac1928675f0d917fa9b3 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Mon, 15 Aug 2016 15:41:22 +0300 Subject: [PATCH 354/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Config/Structure/Element/FieldPlugin.php | 42 +++++----- .../Method/Checks/SpecificationPlugin.php | 3 + .../Structure/Element/FieldPluginTest.php | 81 +++++++++++-------- 3 files changed, 75 insertions(+), 51 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php b/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php index 2d49ddfcb3d..a6288b8fc68 100644 --- a/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php +++ b/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php @@ -5,39 +5,45 @@ */ namespace Magento\Paypal\Model\Config\Structure\Element; +use Magento\Framework\App\RequestInterface; +use Magento\Config\Model\Config\Structure\Element\Field as FieldConfigStructure; +use Magento\Paypal\Model\Config\StructurePlugin as ConfigStructurePlugin; + +/** + * Plugin for \Magento\Config\Model\Config\Structure\Element\Field + */ class FieldPlugin { /** - * @var \Magento\Framework\App\RequestInterface + * @var RequestInterface */ - protected $_request; + private $request; /** - * @param \Magento\Framework\App\RequestInterface $request + * @param RequestInterface $request */ - public function __construct(\Magento\Framework\App\RequestInterface $request) + public function __construct(RequestInterface $request) { - $this->_request = $request; + $this->request = $request; } /** * Get original configPath (not changed by PayPal configuration inheritance) * - * @param \Magento\Config\Model\Config\Structure\Element\Field $subject - * @param \Closure $proceed + * @param FieldConfigStructure $subject + * @param string|null $result * @return string|null */ - public function aroundGetConfigPath( - \Magento\Config\Model\Config\Structure\Element\Field $subject, - \Closure $proceed - ) { - $configPath = $proceed(); - if (!isset($configPath) && $this->_request->getParam('section') == 'payment') { - $configPath = preg_replace('@^(' . implode( - '|', - \Magento\Paypal\Model\Config\StructurePlugin::getPaypalConfigCountries(true) - ) . ')/@', 'payment/', $subject->getPath()); + public function afterGetConfigPath(FieldConfigStructure $subject, $result) + { + if (!$result && $this->request->getParam('section') == 'payment') { + $result = preg_replace( + '@^(' . implode('|', ConfigStructurePlugin::getPaypalConfigCountries(true)) . ')/@', + 'payment/', + $subject->getPath() + ); } - return $configPath; + + return $result; } } diff --git a/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php b/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php index 2ae65a8a70c..f2b650b95e9 100644 --- a/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php +++ b/app/code/Magento/Paypal/Model/Method/Checks/SpecificationPlugin.php @@ -11,6 +11,9 @@ use Magento\Paypal\Model\Config; use Magento\Paypal\Model\Billing\AgreementFactory; use Magento\Quote\Model\Quote; +/** + * Plugin for \Magento\Payment\Model\Checks\Composite + */ class SpecificationPlugin { /** diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php index e630e3c5720..c2c0ff98d4d 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php @@ -3,74 +3,89 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Paypal\Test\Unit\Model\Config\Structure\Element; +use Magento\Paypal\Model\Config\Structure\Element\FieldPlugin as FieldConfigStructurePlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\App\RequestInterface; +use Magento\Config\Model\Config\Structure\Element\Field as FieldConfigStructureMock; + class FieldPluginTest extends \PHPUnit_Framework_TestCase { - /** @var FieldPlugin */ - protected $model; + /** + * @var FieldConfigStructurePlugin + */ + private $plugin; - /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $request; + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + /** + * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; - /** @var \Magento\Config\Model\Config\Structure\Element\Field|\PHPUnit_Framework_MockObject_MockObject */ - protected $subject; + /** + * @var FieldConfigStructureMock|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectMock; protected function setUp() { - $this->request = $this->getMockForAbstractClass(\Magento\Framework\App\RequestInterface::class); - $this->subject = $this->getMock(\Magento\Config\Model\Config\Structure\Element\Field::class, [], [], '', false); + $this->requestMock = $this->getMockBuilder(RequestInterface::class) + ->getMockForAbstractClass(); + $this->subjectMock = $this->getMockBuilder(FieldConfigStructureMock::class) + ->disableOriginalConstructor() + ->getMock(); - $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->model = $helper->getObject( - \Magento\Paypal\Model\Config\Structure\Element\FieldPlugin::class, - ['request' => $this->request] + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + FieldConfigStructurePlugin::class, + ['request' => $this->requestMock] ); } public function testAroundGetConfigPathHasResult() { $someResult = 'some result'; - $callback = function () use ($someResult) { - return $someResult; - }; - $this->assertEquals($someResult, $this->model->aroundGetConfigPath($this->subject, $callback)); + + $this->assertEquals($someResult, $this->plugin->afterGetConfigPath($this->subjectMock, $someResult)); } public function testAroundGetConfigPathNonPaymentSection() { - $callback = function () { - return null; - }; - $this->request->expects($this->once()) + $this->requestMock->expects(static::once()) ->method('getParam') ->with('section') - ->will($this->returnValue('non-payment')); - $this->assertNull($this->model->aroundGetConfigPath($this->subject, $callback)); + ->willReturn('non-payment'); + + $this->assertNull($this->plugin->afterGetConfigPath($this->subjectMock, null)); } /** * @param string $subjectPath * @param string $expectedConfigPath - * @dataProvider aroundGetConfigPathDataProvider + * @dataProvider afterGetConfigPathDataProvider */ public function testAroundGetConfigPath($subjectPath, $expectedConfigPath) { - $callback = function () { - return null; - }; - $this->request->expects($this->once()) + $this->requestMock->expects(static::once()) ->method('getParam') ->with('section') - ->will($this->returnValue('payment')); - $this->subject->expects($this->once()) + ->willReturn('payment'); + $this->subjectMock->expects(static::once()) ->method('getPath') - ->will($this->returnValue($subjectPath)); - $this->assertEquals($expectedConfigPath, $this->model->aroundGetConfigPath($this->subject, $callback)); + ->willReturn($subjectPath); + + $this->assertEquals($expectedConfigPath, $this->plugin->afterGetConfigPath($this->subjectMock, null)); } - public function aroundGetConfigPathDataProvider() + /** + * @return array + */ + public function afterGetConfigPathDataProvider() { return [ ['payment_us/group/field', 'payment/group/field'], -- GitLab From 20d4a7ee9e5dd1d2c27ea97d4231a1314c6c2e54 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Mon, 15 Aug 2016 15:43:27 +0300 Subject: [PATCH 355/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Unit/Model/Config/Structure/Element/FieldPluginTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php index c2c0ff98d4d..13cc51a7dc4 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php @@ -91,7 +91,7 @@ class FieldPluginTest extends \PHPUnit_Framework_TestCase ['payment_us/group/field', 'payment/group/field'], ['payment_other/group/field', 'payment/group/field'], ['payment_us', 'payment_us'], - ['payment_wrong_country/group/field', 'payment_wrong_country/group/field'], + ['payment_wrong_country/group/field', 'payment_wrong_country/group/field'] ]; } } -- GitLab From a61fcd1a95214a24fdc86a1471f71b88e23237d7 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Mon, 15 Aug 2016 16:06:18 +0300 Subject: [PATCH 356/838] MAGETWO-55754: [WCAG 2.0 AA] Image Gallery Thumbnails - Support reverse tabulation on Product page --- .../frontend/layout/catalog_product_view.xml | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml index 730b9089da3..2f8feb52db5 100644 --- a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml +++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml @@ -101,18 +101,31 @@ </block> </container> <container name="product.info.media" htmlTag="div" htmlClass="product media" after="product.info.main"> - <container name="skip_gallery.wrapper" htmlTag="div" htmlClass="action-skip-wrapper"> - <block class="Magento\Framework\View\Element\Template" before="product.info.media.image" name="skip_gallery" template="Magento_Theme::html/skip.phtml"> + <block class="Magento\Framework\View\Element\Template" name="skip_gallery_after.target" before="skip_gallery_before.wrapper" template="Magento_Theme::html/skiptarget.phtml"> + <arguments> + <argument name="target_id" xsi:type="string">gallery-prev-area</argument> + </arguments> + </block> + <container name="skip_gallery_before.wrapper" htmlTag="div" htmlClass="action-skip-wrapper"> + <block class="Magento\Framework\View\Element\Template" before="product.info.media.image" name="skip_gallery_before" template="Magento_Theme::html/skip.phtml"> <arguments> - <argument name="target" xsi:type="string">nextarea</argument> - <argument name="label" translate="true" xsi:type="string">Skip Gallery</argument> + <argument name="target" xsi:type="string">gallery-next-area</argument> + <argument name="label" translate="true" xsi:type="string">Skip to the end of the images gallery</argument> </arguments> </block> </container> <block class="Magento\Catalog\Block\Product\View\Gallery" name="product.info.media.image" template="product/view/gallery.phtml"/> - <block class="Magento\Framework\View\Element\Template" name="skip_gallery.target" after="product.info.media.image" template="Magento_Theme::html/skiptarget.phtml"> + <container name="skip_gallery_after.wrapper" htmlTag="div" htmlClass="action-skip-wrapper"> + <block class="Magento\Framework\View\Element\Template" after="product.info.media.image" name="skip_gallery_after" template="Magento_Theme::html/skip.phtml"> + <arguments> + <argument name="target" xsi:type="string">gallery-prev-area</argument> + <argument name="label" translate="true" xsi:type="string">Skip to the beginning of the images gallery</argument> + </arguments> + </block> + </container> + <block class="Magento\Framework\View\Element\Template" name="skip_gallery_before.target" after="skip_gallery_after.wrapper" template="Magento_Theme::html/skiptarget.phtml"> <arguments> - <argument name="target_id" xsi:type="string">nextarea</argument> + <argument name="target_id" xsi:type="string">gallery-next-area</argument> </arguments> </block> </container> -- GitLab From 2c4e3a7e07a8725b7bd601aaaadf171c54ea6dbf Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Mon, 15 Aug 2016 16:20:19 +0300 Subject: [PATCH 357/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../GiftMessage/Model/Plugin/QuoteItem.php | 32 ++++++++++--------- .../Test/Unit/Model/Plugin/QuoteItemTest.php | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php index 0faee488bae..6a8c2191cf9 100644 --- a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php +++ b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php @@ -5,40 +5,42 @@ */ namespace Magento\GiftMessage\Model\Plugin; -use Closure; -use Magento\Sales\Model\Order\Item; +use Magento\Sales\Api\Data\OrderItemInterface; +use Magento\GiftMessage\Helper\Message as HelperMessage; +use Magento\Quote\Model\Quote\Item\ToOrderItem; +use Magento\Quote\Model\Quote\Item\AbstractItem; class QuoteItem { /** - * @var \Magento\GiftMessage\Helper\Message + * @var HelperMessage */ protected $_helper; /** - * @param \Magento\GiftMessage\Helper\Message $helper + * @param HelperMessage $helper */ - public function __construct(\Magento\GiftMessage\Helper\Message $helper) + public function __construct(HelperMessage $helper) { $this->_helper = $helper; } /** - * @param \Magento\Quote\Model\Quote\Item\ToOrderItem $subject - * @param callable $proceed - * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item + * Apply gift message per every item in order if available + * + * @param ToOrderItem $subject + * @param OrderItemInterface $orderItem + * @param AbstractItem $item * @param array $additional - * @return Item + * @return OrderItemInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundConvert( - \Magento\Quote\Model\Quote\Item\ToOrderItem $subject, - Closure $proceed, - \Magento\Quote\Model\Quote\Item\AbstractItem $item, + public function afterConvert( + ToOrderItem $subject, + OrderItemInterface $orderItem, + AbstractItem $item, $additional = [] ) { - /** @var $orderItem Item */ - $orderItem = $proceed($item, $additional); $isAvailable = $this->_helper->isMessagesAllowed('item', $item, $item->getStoreId()); $orderItem->setGiftMessageId($item->getGiftMessageId()); diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php index ad099bebc88..91fa2575ed3 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php @@ -99,7 +99,7 @@ class QuoteItemTest extends \PHPUnit_Framework_TestCase $this->assertSame( $this->orderItemMock, - $this->model->aroundConvert($this->subjectMock, $this->closureMock, $this->quoteItemMock, []) + $this->model->afterConvert($this->subjectMock, $this->orderItemMock, $this->quoteItemMock, []) ); } } -- GitLab From b8c11f02cb5536316b4464d2378754c7c7781f59 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Mon, 15 Aug 2016 16:37:22 +0300 Subject: [PATCH 358/838] MAGETWO-56778: Value for multiple select attribute does not save --- .../Magento/Eav/Model/Entity/AttributeLoader.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index 0cac11516d5..9726b38d5c5 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -64,8 +64,16 @@ class AttributeLoader implements AttributeLoaderInterface */ public function loadAllAttributes(AbstractEntity $resource, DataObject $object = null) { + $attributeSetId = 0; + $storeId = 0; + if ($object instanceof \Magento\Framework\DataObject) { + $attributeSetId = $object->getAttributeSetId() ?: $attributeSetId; + $storeId = $object->getStoreId() ?: $storeId; + } + $suffix = $storeId . '-' . $attributeSetId; + $typeCode = $resource->getEntityType()->getEntityTypeCode(); - $attributes = $this->cache->getAttributes($typeCode); + $attributes = $this->cache->getAttributes($typeCode, $suffix); if ($attributes) { foreach ($attributes as $attribute) { $resource->addAttribute($attribute); @@ -95,7 +103,7 @@ class AttributeLoader implements AttributeLoaderInterface $attribute = $resource->getAttribute($code); $attributes[] = $attribute; } - $this->cache->saveAttributes($typeCode, $attributes); + $this->cache->saveAttributes($typeCode, $attributes, $suffix); return $resource; } -- GitLab From b52635825bafa3f0a0659cf8110166ef306eb34b Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Mon, 15 Aug 2016 16:47:38 +0300 Subject: [PATCH 359/838] MAGETWO-56778: Value for multiple select attribute does not save --- app/code/Magento/Eav/Model/Entity/AttributeLoader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index 9726b38d5c5..adc8e56e4ba 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -61,6 +61,7 @@ class AttributeLoader implements AttributeLoaderInterface * @param DataObject|null $object * @return AbstractEntity * @throws \Magento\Framework\Exception\LocalizedException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function loadAllAttributes(AbstractEntity $resource, DataObject $object = null) { -- GitLab From 7b7af8af3596edbd6ad3c75897609940458c7e14 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 15 Aug 2016 17:37:59 +0300 Subject: [PATCH 360/838] MAGETWO-56702: Refactor plugins --- .../Model/Category/Plugin/Store/View.php | 29 ++- .../Model/Category/Plugin/Store/ViewTest.php | 185 ++++++++++++++++++ 2 files changed, 199 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php index ade02f84469..516d1200f2f 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php @@ -31,6 +31,9 @@ class View /** @var ProductUrlRewriteGenerator */ protected $productUrlRewriteGenerator; + /** @var AbstractModel */ + private $store; + /** * @param UrlPersistInterface $urlPersist * @param CategoryFactory $categoryFactory @@ -53,19 +56,17 @@ class View } /** - * @param \Magento\Store\Model\ResourceModel\Store $object - * @param callable $proceed + * @param \Magento\Store\Model\ResourceModel\Store $subject + * @param \Magento\Store\Model\ResourceModel\Store $result * @param AbstractModel $store * @return \Magento\Store\Model\ResourceModel\Store * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundSave( - \Magento\Store\Model\ResourceModel\Store $object, - \Closure $proceed, + public function afterSave( + \Magento\Store\Model\ResourceModel\Store $subject, + \Magento\Store\Model\ResourceModel\Store $result, AbstractModel $store ) { - $originStore = $store; - $result = $proceed($originStore); if ($store->isObjectNew() || $store->dataHasChangedFor('group_id')) { if (!$store->isObjectNew()) { $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $store->getId()]); @@ -79,7 +80,6 @@ class View $this->generateProductUrls($store->getWebsiteId(), $store->getOrigData('website_id'), $store->getId()) ); } - return $result; } @@ -134,18 +134,17 @@ class View } /** - * @param \Magento\Store\Model\ResourceModel\Store $object - * @param callable $proceed + * @param \Magento\Store\Model\ResourceModel\Store $subject + * @param \Magento\Store\Model\ResourceModel\Store $result * @param AbstractModel $store - * @return mixed + * @return \Magento\Store\Model\ResourceModel\Store * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDelete( - \Magento\Store\Model\ResourceModel\Store $object, - \Closure $proceed, + public function afterDelete( + \Magento\Store\Model\ResourceModel\Store $subject, + \Magento\Store\Model\ResourceModel\Store $result, AbstractModel $store ) { - $result = $proceed($store); $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $store->getId()]); return $result; } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php new file mode 100644 index 00000000000..8b6658c3fa4 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php @@ -0,0 +1,185 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Store; + +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\View; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Model\AbstractModel; +use Magento\Store\Model\ResourceModel\Store; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\Catalog\Model\CategoryFactory; +use Magento\Catalog\Model\ProductFactory; +use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Model\Product as Product; + +class ViewTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var View + */ + private $plugin; + + /** + * @var AbstractModel|\PHPUnit_Framework_MockObject_MockObject + */ + private $abstractModelMock; + + /** + * @var Store|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectMock; + + /** + * @var UrlPersistInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $urlPersistMock; + + /** + * @var CategoryFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryFactoryMock; + + /** + * @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $productFactoryMock; + + /** + * @var CategoryUrlRewriteGenerator|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryUrlRewriteGeneratorMock; + + /** + * @var ProductUrlRewriteGenerator|\PHPUnit_Framework_MockObject_MockObject + */ + private $productUrlRewriteGeneratorMock; + + /** + * @var Category|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryMock; + + /** + * @var ProductCollection|\PHPUnit_Framework_MockObject_MockObject + */ + private $productCollectionMock; + + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $productMock; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->abstractModelMock = $this->getMockBuilder(AbstractModel::class) + ->disableOriginalConstructor() + ->setMethods(['isObjectNew']) + ->getMockForAbstractClass(); + $this->subjectMock = $this->getMockBuilder(Store::class) + ->disableOriginalConstructor() + ->getMock(); + $this->urlPersistMock = $this->getMockBuilder(UrlPersistInterface::class) + ->setMethods(['deleteByData']) + ->getMockForAbstractClass(); + $this->categoryMock = $this->getMockBuilder(Category::class) + ->disableOriginalConstructor() + ->setMethods(['getCategories']) + ->getMock(); + $this->categoryFactoryMock = $this->getMockBuilder(CategoryFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->productFactoryMock = $this->getMockBuilder(ProductFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->categoryUrlRewriteGeneratorMock = $this->getMockBuilder(CategoryUrlRewriteGenerator::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productUrlRewriteGeneratorMock = $this->getMockBuilder(ProductUrlRewriteGenerator::class) + ->disableOriginalConstructor() + ->setMethods(['generate']) + ->getMock(); + $this->productCollectionMock = $this->getMockBuilder(ProductCollection::class) + ->disableOriginalConstructor() + ->setMethods(['addCategoryIds', 'addAttributeToSelect', 'addWebsiteFilter', 'getIterator']) + ->getMock(); + $this->productMock = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getCollection']) + ->getMock(); + $this->plugin = $this->objectManager->getObject( + View::class, + [ + 'urlPersist' => $this->urlPersistMock, + 'categoryFactory' => $this->categoryFactoryMock, + 'productFactory' => $this->productFactoryMock, + 'categoryUrlRewriteGenerator' => $this->categoryUrlRewriteGeneratorMock, + 'productUrlRewriteGenerator' => $this->productUrlRewriteGeneratorMock + ] + ); + } + + public function testAfterSave() + { + $this->abstractModelMock->expects($this->any()) + ->method('isObjectNew') + ->willReturn(true); + $this->categoryMock->expects($this->once()) + ->method('getCategories') + ->willReturn([]); + $this->categoryFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->categoryMock); + $this->productFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->productMock); + $this->productMock->expects($this->once()) + ->method('getCollection') + ->willReturn($this->productCollectionMock); + $this->productCollectionMock->expects($this->once()) + ->method('addCategoryIds') + ->willReturn($this->productCollectionMock); + $this->productCollectionMock->expects($this->once()) + ->method('addAttributeToSelect') + ->willReturn($this->productCollectionMock); + $this->productCollectionMock->expects($this->once()) + ->method('addWebsiteFilter') + ->willReturn($this->productCollectionMock); + $iterator = new \ArrayIterator([$this->productMock]); + $this->productCollectionMock->expects($this->once()) + ->method('getIterator') + ->willReturn($iterator); + $this->productUrlRewriteGeneratorMock->expects($this->once()) + ->method('generate') + ->with($this->productMock) + ->willReturn([]); + + $this->assertEquals( + $this->subjectMock, + $this->plugin->afterSave($this->subjectMock, $this->subjectMock, $this->abstractModelMock) + ); + } + + public function testAfterDelete() + { + $this->urlPersistMock->expects($this->once()) + ->method('deleteByData'); + $this->assertEquals( + $this->subjectMock, + $this->plugin->afterDelete($this->subjectMock, $this->subjectMock, $this->abstractModelMock) + ); + } +} -- GitLab From bb78c1d612b95a8d27956ffd4e688ae3ec27268c Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 15 Aug 2016 17:39:28 +0300 Subject: [PATCH 361/838] MAGETWO-56702: Refactor plugins --- .../CatalogUrlRewrite/Model/Category/Plugin/Store/View.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php index 516d1200f2f..a181e685925 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php @@ -5,7 +5,6 @@ */ namespace Magento\CatalogUrlRewrite\Model\Category\Plugin\Store; -use Magento\Catalog\Model\Category; use Magento\Catalog\Model\CategoryFactory; use Magento\Catalog\Model\ProductFactory; use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; @@ -31,9 +30,6 @@ class View /** @var ProductUrlRewriteGenerator */ protected $productUrlRewriteGenerator; - /** @var AbstractModel */ - private $store; - /** * @param UrlPersistInterface $urlPersist * @param CategoryFactory $categoryFactory -- GitLab From 1afb2ea75e3eb05bf10a57671359763593f65b85 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Mon, 15 Aug 2016 17:56:16 +0300 Subject: [PATCH 362/838] MAGETWO-55193: Extension Management with Marketplace data - Remove form extension greed unnecessary package types --- .../Setup/Controller/InstallExtensionGrid.php | 17 +---- .../Magento/Setup/Model/Grid/Extension.php | 17 +---- setup/src/Magento/Setup/Model/Grid/Module.php | 30 +------- .../Magento/Setup/Model/Grid/TypeMapper.php | 59 ++++----------- .../src/Magento/Setup/Model/PackagesData.php | 71 ++++++++++++++++--- .../Controller/InstallExtensionGridTest.php | 26 ++----- .../Test/Unit/Model/Grid/ExtensionTest.php | 49 ++++--------- .../Setup/Test/Unit/Model/Grid/ModuleTest.php | 47 ++++-------- .../Test/Unit/Model/Grid/TypeMapperTest.php | 40 ++--------- .../Test/Unit/Model/PackagesDataTest.php | 26 +++++-- setup/view/magento/setup/extension-grid.phtml | 4 +- .../setup/install-extension-grid.phtml | 8 +-- setup/view/magento/setup/module-grid.phtml | 6 +- .../magento/setup/update-extension-grid.phtml | 8 +-- 14 files changed, 157 insertions(+), 251 deletions(-) diff --git a/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php b/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php index 706fbbcbac1..0821b6ab2ff 100644 --- a/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php +++ b/setup/src/Magento/Setup/Controller/InstallExtensionGrid.php @@ -10,7 +10,6 @@ use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\JsonModel; use Zend\View\Model\ViewModel; use Magento\Setup\Model\PackagesData; -use \Magento\Setup\Model\Grid\TypeMapper; /** * Controller for extensions grid tasks @@ -22,21 +21,13 @@ class InstallExtensionGrid extends AbstractActionController */ private $packagesData; - /** - * @var TypeMapper - */ - private $typeMapper; - /** * @param PackagesData $packagesData - * @param TypeMapper $typeMapper */ public function __construct( - PackagesData $packagesData, - TypeMapper $typeMapper + PackagesData $packagesData ) { $this->packagesData = $packagesData; - $this->typeMapper = $typeMapper; } /** @@ -81,12 +72,6 @@ class InstallExtensionGrid extends AbstractActionController { array_walk($packages, function (&$package) { $package['vendor'] = ucfirst($package['vendor']); - $package['link'] = isset($package['extra']['x-magento-ext-package-link']) ? - $package['extra']['x-magento-ext-package-link'] : ''; - $package['product_name'] = isset($package['extra']['x-magento-ext-title']) ? - $package['extra']['x-magento-ext-title'] : $package['name']; - $package['type'] = isset($package['extra']['x-magento-ext-type']) ? - $package['extra']['x-magento-ext-type'] : $this->typeMapper->map($package['name'], $package['type']); }); return $packages; diff --git a/setup/src/Magento/Setup/Model/Grid/Extension.php b/setup/src/Magento/Setup/Model/Grid/Extension.php index d02c78b7bf9..d46a112cc8b 100644 --- a/setup/src/Magento/Setup/Model/Grid/Extension.php +++ b/setup/src/Magento/Setup/Model/Grid/Extension.php @@ -18,11 +18,6 @@ class Extension */ private $composerInformation; - /** - * @var TypeMapper - */ - private $typeMapper; - /** * @var PackagesData */ @@ -31,16 +26,13 @@ class Extension /** * @param ComposerInformation $composerInformation * @param PackagesData $packagesData - * @param TypeMapper $typeMapper */ public function __construct( ComposerInformation $composerInformation, - PackagesData $packagesData, - TypeMapper $typeMapper + PackagesData $packagesData ) { $this->composerInformation = $composerInformation; $this->packagesData = $packagesData; - $this->typeMapper = $typeMapper; } /** @@ -88,14 +80,7 @@ class Extension private function formatExtensions(array $extensions) { foreach ($extensions as &$extension) { - $extraInfo = $this->packagesData->getPackageExtraInfo($extension['name'], $extension['version']); $extension['vendor'] = ucfirst(current(explode('/', $extension['name']))); - $extension['product_name'] = isset($extraInfo['x-magento-ext-title']) ? - $extraInfo['x-magento-ext-title'] : $extension['name']; - $extension['type'] = isset($extraInfo['x-magento-ext-type']) ? - $extraInfo['x-magento-ext-type'] : $this->typeMapper->map($extension['name'], $extension['type']); - $extension['link'] = isset($extraInfo['x-magento-ext-package-link']) ? - $extraInfo['x-magento-ext-package-link'] : ''; } return array_values($extensions); } diff --git a/setup/src/Magento/Setup/Model/Grid/Module.php b/setup/src/Magento/Setup/Model/Grid/Module.php index 9373f090798..bda7e001d6a 100644 --- a/setup/src/Magento/Setup/Model/Grid/Module.php +++ b/setup/src/Magento/Setup/Model/Grid/Module.php @@ -52,11 +52,6 @@ class Module */ private $moduleList; - /** - * @var TypeMapper - */ - private $typeMapper; - /** * @var PackagesData */ @@ -67,7 +62,6 @@ class Module * @param \Magento\Framework\Module\FullModuleList $fullModuleList * @param ModuleList $moduleList * @param \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider - * @param TypeMapper $typeMapper * @param PackagesData $packagesData */ public function __construct( @@ -75,14 +69,12 @@ class Module \Magento\Framework\Module\FullModuleList $fullModuleList, ModuleList $moduleList, \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider, - TypeMapper $typeMapper, PackagesData $packagesData ) { $this->composerInformation = $composerInformation; $this->fullModuleList = $fullModuleList; $this->moduleList = $moduleList; $this->objectManagerProvider = $objectManagerProvider; - $this->typeMapper = $typeMapper; $this->packagesData = $packagesData; } @@ -169,6 +161,7 @@ class Module $result[$key] = [ 'name' => $packageName ?: self::UNKNOWN_PACKAGE_NAME, 'moduleName' => $moduleName, + 'type' => ComposerInformation::MODULE_PACKAGE_TYPE, 'version' => $this->packageInfo->getVersion($moduleName) ?: self::UNKNOWN_VERSION, ]; } @@ -189,28 +182,9 @@ class Module $item['enable'] = $this->moduleList->has($item['moduleName']); $vendorSource = $item['name'] == self::UNKNOWN_PACKAGE_NAME ? $item['moduleName'] : $item['name']; $item['vendor'] = ucfirst(current(preg_split('%[/_]%', $vendorSource))); + $item = $this->packagesData->addPackageExtraInfo($item); } - $items = $this->addExtraInfo($items); return array_values($items); } - - /** - * Add extra info to result array - * - * @param array $items - * @return array - */ - private function addExtraInfo(array $items) - { - foreach ($items as &$item) { - $extraInfo = $this->packagesData->getPackageExtraInfo($item['name'], $item['version']); - $item['product_name'] = isset($extraInfo['x-magento-ext-title']) ? - $extraInfo['x-magento-ext-title'] : $item['name']; - $item['type'] = isset($extraInfo['x-magento-ext-type']) ? $extraInfo['x-magento-ext-type'] : - $this->typeMapper->map($item['name'], ComposerInformation::MODULE_PACKAGE_TYPE); - } - - return $items; - } } diff --git a/setup/src/Magento/Setup/Model/Grid/TypeMapper.php b/setup/src/Magento/Setup/Model/Grid/TypeMapper.php index 962baa79f24..5c31c9a183d 100644 --- a/setup/src/Magento/Setup/Model/Grid/TypeMapper.php +++ b/setup/src/Magento/Setup/Model/Grid/TypeMapper.php @@ -17,65 +17,34 @@ class TypeMapper */ const UNDEFINED_PACKAGE_TYPE = 'Undefined'; const EXTENSION_PACKAGE_TYPE = 'Extension'; + const THEME_PACKAGE_TYPE = 'Theme'; + const MODULE_PACKAGE_TYPE = 'Module'; + const LANGUAGE_PACKAGE_TYPE = 'Language'; + const METAPACKAGE_PACKAGE_TYPE = 'Metapackage'; + const COMPONENT_PACKAGE_TYPE = 'Component'; + const LIBRARY_PACKAGE_TYPE = 'Library'; /**#@-*/ - - /** - * @var ComposerInformation - */ - private $composerInformation; - - /** - * @var array - */ - private $rootRequires; /** @var array */ private $packageTypesMap = [ - ComposerInformation::THEME_PACKAGE_TYPE => 'Theme', - ComposerInformation::LANGUAGE_PACKAGE_TYPE => 'Language', - ComposerInformation::MODULE_PACKAGE_TYPE => 'Module', - ComposerInformation::METAPACKAGE_PACKAGE_TYPE => 'Metapackage', - ComposerInformation::COMPONENT_PACKAGE_TYPE => 'Component', - ComposerInformation::LIBRARY_PACKAGE_TYPE => 'Library' + ComposerInformation::THEME_PACKAGE_TYPE => self::THEME_PACKAGE_TYPE, + ComposerInformation::LANGUAGE_PACKAGE_TYPE => self::LANGUAGE_PACKAGE_TYPE, + ComposerInformation::MODULE_PACKAGE_TYPE => self::MODULE_PACKAGE_TYPE, + ComposerInformation::METAPACKAGE_PACKAGE_TYPE => self::METAPACKAGE_PACKAGE_TYPE, + ComposerInformation::COMPONENT_PACKAGE_TYPE => self::COMPONENT_PACKAGE_TYPE, + ComposerInformation::LIBRARY_PACKAGE_TYPE => self::LIBRARY_PACKAGE_TYPE ]; - /** - * TypeMapper constructor. - * @param ComposerInformation $composerInformation - */ - public function __construct( - ComposerInformation $composerInformation - ) { - $this->composerInformation = $composerInformation; - } - /** * Retrieve package type for a grid. * - * @param string $packageName * @param string $packageType * @return string + * @internal param string $packageName */ - public function map($packageName, $packageType) + public function map($packageType) { - if (in_array($packageName, $this->getRootRequires()) - && $packageType == ComposerInformation::MODULE_PACKAGE_TYPE - ) { - return self::EXTENSION_PACKAGE_TYPE; - } - return isset($this->packageTypesMap[$packageType]) ? $this->packageTypesMap[$packageType] : self::UNDEFINED_PACKAGE_TYPE; } - - /** - * @return array - */ - private function getRootRequires() - { - if ($this->rootRequires === null) { - $this->rootRequires = array_keys($this->composerInformation->getRootPackage()->getRequires()); - } - return $this->rootRequires; - } } diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index 4a37fb72421..52334ba5582 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -62,24 +62,27 @@ class PackagesData /** * PackagesData constructor. * - * @param \Magento\Framework\Composer\ComposerInformation $composerInformation, - * @param \Magento\Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider, - * @param \Magento\Setup\Model\PackagesAuth $packagesAuth, - * @param \Magento\Framework\Filesystem $filesystem, + * @param \Magento\Framework\Composer\ComposerInformation $composerInformation , + * @param \Magento\Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider , + * @param \Magento\Setup\Model\PackagesAuth $packagesAuth , + * @param \Magento\Framework\Filesystem $filesystem , * @param \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider + * @param TypeMapper $typeMapper */ public function __construct( \Magento\Framework\Composer\ComposerInformation $composerInformation, \Magento\Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider, \Magento\Setup\Model\PackagesAuth $packagesAuth, \Magento\Framework\Filesystem $filesystem, - \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider + \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider, + \Magento\Setup\Model\Grid\TypeMapper $typeMapper ) { $this->objectManagerProvider = $objectManagerProvider; $this->composerInformation = $composerInformation; $this->timeZoneProvider = $timeZoneProvider; $this->packagesAuth = $packagesAuth; $this->filesystem = $filesystem; + $this->typeMapper = $typeMapper; } /** @@ -172,10 +175,16 @@ class PackagesData */ public function getInstalledPackages() { - return array_intersect_key( + $installedPackages = array_intersect_key( $this->composerInformation->getInstalledMagentoPackages(), $this->composerInformation->getRootPackage()->getRequires() ); + + foreach ($installedPackages as &$package) { + $package = $this->addPackageExtraInfo($package); + } + + return $this->filterPackagesList($installedPackages); } /** @@ -276,11 +285,11 @@ class PackagesData $installPackage['versions'] = $versions; $installPackage['name'] = $packageName; $installPackage['vendor'] = explode('/', $packageName)[0]; - $installPackages[$packageName] = $installPackage; + $installPackages[$packageName] = $this->addPackageExtraInfo($installPackage); } } } - $packagesForInstall['packages'] = $installPackages; + $packagesForInstall['packages'] = $this->filterPackagesList($installPackages); return $packagesForInstall; } catch (\Exception $e) { throw new \RuntimeException('Error in syncing packages for Install'); @@ -294,7 +303,7 @@ class PackagesData * @param string $packageVersion * @return array */ - public function getPackageExtraInfo($packageName, $packageVersion) + private function getPackageExtraInfo($packageName, $packageVersion) { $packagesJson = $this->getPackagesJson(); @@ -302,6 +311,26 @@ class PackagesData $packagesJson[$packageName][$packageVersion]['extra'] : [] ; } + /** + * Add package extra info + * + * @param array $package + * @return array + */ + public function addPackageExtraInfo(array $package) + { + $extraInfo = $this->getPackageExtraInfo($package['name'], $package['version']); + + $package['package_title'] = isset($extraInfo['x-magento-ext-title']) ? + $extraInfo['x-magento-ext-title'] : $package['name']; + $package['package_type'] = isset($extraInfo['x-magento-ext-type']) ? $extraInfo['x-magento-ext-type'] : + $this->typeMapper->map($package['type']); + $package['package_link'] = isset($extraInfo['x-magento-ext-package-link']) ? + $extraInfo['x-magento-ext-package-link'] : ''; + + return $package; + } + /** * Check if this new user package * @@ -365,6 +394,30 @@ class PackagesData } } + /** + * Filter packages by allowed types + * + * @param array $packages + * @return array + */ + private function filterPackagesList(array $packages) + { + return array_filter( + $packages, + function ($item) { + return in_array( + $item['package_type'], + [ + \Magento\Setup\Model\Grid\TypeMapper::MODULE_PACKAGE_TYPE, + \Magento\Setup\Model\Grid\TypeMapper::EXTENSION_PACKAGE_TYPE, + \Magento\Setup\Model\Grid\TypeMapper::THEME_PACKAGE_TYPE, + \Magento\Setup\Model\Grid\TypeMapper::METAPACKAGE_PACKAGE_TYPE + ] + ); + } + ); + } + /** * * @param array $packages diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/InstallExtensionGridTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/InstallExtensionGridTest.php index 9b091b0bc12..166942a695d 100644 --- a/setup/src/Magento/Setup/Test/Unit/Controller/InstallExtensionGridTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Controller/InstallExtensionGridTest.php @@ -7,8 +7,8 @@ namespace Magento\Setup\Test\Unit\Controller; use Magento\Setup\Controller\InstallExtensionGrid; -use Magento\Setup\Model\Grid\TypeMapper; use Magento\Setup\Model\PackagesData; +use Magento\Framework\Composer\ComposerInformation; class InstallExtensionGridTest extends \PHPUnit_Framework_TestCase { @@ -24,23 +24,14 @@ class InstallExtensionGridTest extends \PHPUnit_Framework_TestCase */ private $packagesData; - /** - * @var TypeMapper|\PHPUnit_Framework_MockObject_MockObject - */ - private $typeMapperMock; - public function setUp() { $this->packagesData = $this->getMockBuilder(PackagesData::class) ->disableOriginalConstructor() ->getMock(); - $this->typeMapperMock = $this->getMockBuilder(TypeMapper::class) - ->disableOriginalConstructor() - ->getMock(); $this->controller = new InstallExtensionGrid( - $this->packagesData, - $this->typeMapperMock + $this->packagesData ); } @@ -63,9 +54,6 @@ class InstallExtensionGridTest extends \PHPUnit_Framework_TestCase $this->packagesData->expects(static::once()) ->method('getPackagesForInstall') ->willReturn($extensions); - $this->typeMapperMock->expects(static::exactly(4)) - ->method('map') - ->willReturn($extensions); $jsonModel = $this->controller->extensionsAction(); static::assertInstanceOf(\Zend\View\Model\JsonModel::class, $jsonModel); @@ -84,25 +72,25 @@ class InstallExtensionGridTest extends \PHPUnit_Framework_TestCase $extensions['packages'] = [ 'magento/testing-extension' => [ 'name' => 'magento/testing-extension', - 'type' => 'module', + 'type' => ComposerInformation::MODULE_PACKAGE_TYPE, 'vendor' => 'magento', 'version' => '2.2.2', 'author' => 'magento'], 'magento/my-first-module' => [ 'name' => 'magento/my-first-module', - 'type' => 'module', + 'type' => ComposerInformation::MODULE_PACKAGE_TYPE, 'vendor' => 'magento', 'version' => '2.0.0', 'author' => 'magento'], 'magento/last-extension' => [ - 'name' => 'magento/last-extension', - 'type' => 'module', + 'name' => 'magento/theme', + 'type' => ComposerInformation::THEME_PACKAGE_TYPE, 'vendor' => 'magento', 'version' => '2.1.1', 'author' => 'magento'], 'magento/magento-second-module' => [ 'name' => 'magento/magento-second-module', - 'type' => 'module', + 'type' => ComposerInformation::COMPONENT_PACKAGE_TYPE, 'vendor' => 'magento', 'version' => '2.0.0', 'author' => 'magento'] diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php index 2603338c342..b80423718e0 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ExtensionTest.php @@ -5,10 +5,8 @@ */ namespace Magento\Setup\Test\Unit\Model\Grid; -use Composer\Package\RootPackage; use Magento\Framework\Composer\ComposerInformation; use Magento\Setup\Model\Grid\Extension; -use Magento\Setup\Model\Grid\TypeMapper; use Magento\Setup\Model\PackagesData; use PHPUnit_Framework_MockObject_MockObject as MockObject; @@ -22,11 +20,6 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase */ private $composerInformationMock; - /** - * @var TypeMapper|MockObject - */ - private $typeMapperMock; - /** * @var PackagesData|MockObject */ @@ -44,17 +37,13 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase $this->composerInformationMock = $this->getMockBuilder(ComposerInformation::class) ->disableOriginalConstructor() ->getMock(); - $this->typeMapperMock = $this->getMockBuilder(TypeMapper::class) - ->disableOriginalConstructor() - ->getMock(); $this->packagesDataMock = $this->getMockBuilder(PackagesData::class) ->disableOriginalConstructor() ->getMock(); $this->model = new Extension( $this->composerInformationMock, - $this->packagesDataMock, - $this->typeMapperMock + $this->packagesDataMock ); } @@ -63,9 +52,6 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase $this->composerInformationMock->expects($this->any()) ->method('isPackageInComposerJson') ->willReturn(true); - $this->typeMapperMock->expects($this->any()) - ->method('map') - ->willReturn('Extension'); $this->packagesDataMock->expects($this->once()) ->method('getInstalledPackages') ->willReturn( @@ -73,11 +59,17 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase 'magento/package-1' => [ 'name' => 'magento/package-1', 'type' => 'magento2-module', + 'package_title' => 'packageTitle', + 'package_type' => 'packageType', + 'package_link' => 'http://example.com', 'version' => '1.0.0' ], 'magento/package-2' => [ 'name' => 'magento/package-2', 'type' => 'magento2-module', + 'package_title' => 'packageTitle', + 'package_type' => 'packageType', + 'package_link' => 'http://example.com', 'version' => '1.0.1' ], ] @@ -90,39 +82,28 @@ class ExtensionTest extends \PHPUnit_Framework_TestCase ] ); - $this->packagesDataMock->expects($this->exactly(2)) - ->method('getPackageExtraInfo') - ->willReturnMap( - [ - ['magento/package-1', '1.0.0', []], - [ - 'magento/package-2', - '1.0.1', - ['x-magento-ext-title'=> 'Package2 title', 'x-magento-ext-package-link' => 'http://example.com'] - ], - ] - ); - $expected = [ [ 'name' => 'magento/package-1', - 'product_name' => 'magento/package-1', - 'type' => 'Extension', + 'type' => 'magento2-module', + 'package_title' => 'packageTitle', + 'package_type' => 'packageType', 'version' => '1.0.0', 'update' => true, 'uninstall' => true, 'vendor' => 'Magento', - 'link' => '', + 'package_link' => 'http://example.com' ], [ 'name' => 'magento/package-2', - 'product_name' => 'Package2 title', - 'type' => 'Extension', + 'type' => 'magento2-module', + 'package_title' => 'packageTitle', + 'package_type' => 'packageType', 'version' => '1.0.1', 'update' => false, 'uninstall' => true, 'vendor' => 'Magento', - 'link' => 'http://example.com', + 'package_link' => 'http://example.com' ], ]; diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php index c0bcfb9b7b0..3d85b2168c5 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/ModuleTest.php @@ -13,7 +13,6 @@ use Magento\Framework\Module\PackageInfo; use Magento\Framework\Module\PackageInfoFactory; use Magento\Framework\ObjectManagerInterface; use Magento\Setup\Model\Grid\Module; -use Magento\Setup\Model\Grid\TypeMapper; use Magento\Setup\Model\ObjectManagerProvider; use Magento\Setup\Model\PackagesData; @@ -55,11 +54,6 @@ class ModuleTest extends \PHPUnit_Framework_TestCase */ private $objectManagerProvider; - /** - * @var TypeMapper|\PHPUnit_Framework_MockObject_MockObject - */ - private $typeMapperMock; - /** * @var PackagesData|\PHPUnit_Framework_MockObject_MockObject */ @@ -119,10 +113,6 @@ class ModuleTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $this->typeMapperMock = $this->getMockBuilder(TypeMapper::class) - ->disableOriginalConstructor() - ->getMock(); - $this->packagesDataMock = $this->getMockBuilder(PackagesData::class) ->disableOriginalConstructor() ->getMock(); @@ -132,7 +122,6 @@ class ModuleTest extends \PHPUnit_Framework_TestCase $this->fullModuleListMock, $this->moduleListMock, $this->objectManagerProvider, - $this->typeMapperMock, $this->packagesDataMock ); } @@ -155,12 +144,6 @@ class ModuleTest extends \PHPUnit_Framework_TestCase $this->packageInfoMock->expects(static::never()) ->method('getModuleName'); - $this->typeMapperMock->expects(static::once()) - ->method('map') - ->willReturnMap([ - [Module::UNKNOWN_PACKAGE_NAME, 'magento2-module', 'Module'], - ]); - $this->packageInfoMock->expects(static::once()) ->method('getRequiredBy') ->willReturn([]); @@ -178,18 +161,14 @@ class ModuleTest extends \PHPUnit_Framework_TestCase ]); $this->packagesDataMock->expects(static::exactly(2)) - ->method('getPackageExtraInfo') - ->willReturnMap([ - [ - 'magento/sample-module-one', - '1.0.0', - [ - 'x-magento-ext-title' => 'Sample Module Full Name', - 'x-magento-ext-type' => 'Extension' - - ] - ], - ]); + ->method('addPackageExtraInfo') + ->will( + $this->returnCallback(function ($package) { + $package['package_title'] = 'packageTitle'; + $package['package_type'] = 'packageType'; + return $package; + }) + ); $this->moduleListMock->expects(static::exactly(2)) ->method('has') @@ -201,22 +180,24 @@ class ModuleTest extends \PHPUnit_Framework_TestCase $expected = [ [ 'name' => 'magento/sample-module-one', - 'type' => 'Extension', + 'type' => 'magento2-module', 'version' => '1.0.0', 'vendor' => 'Magento', 'moduleName' => 'Sample_ModuleOne', 'enable' => true, - 'product_name' => 'Sample Module Full Name', + 'package_title' => 'packageTitle', + 'package_type' => 'packageType', 'requiredBy' => [], ], [ 'name' => Module::UNKNOWN_PACKAGE_NAME, - 'type' => 'Module', + 'type' => 'magento2-module', 'version' => Module::UNKNOWN_VERSION, 'vendor' => 'Sample', 'moduleName' => 'Sample_ModuleTwo', 'enable' => true, - 'product_name' => Module::UNKNOWN_PACKAGE_NAME, + 'package_title' => 'packageTitle', + 'package_type' => 'packageType', 'requiredBy' => [], ], ]; diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Grid/TypeMapperTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Grid/TypeMapperTest.php index 63bcb4f1de0..92d7df7973d 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Grid/TypeMapperTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Grid/TypeMapperTest.php @@ -8,18 +8,12 @@ namespace Magento\Setup\Test\Unit\Model\Grid; use Magento\Framework\Composer\ComposerInformation; use Magento\Setup\Model\Grid\TypeMapper; -use Composer\Package\RootPackageInterface; /** * Class TypeMapperTest */ class TypeMapperTest extends \PHPUnit_Framework_TestCase { - /** - * @var ComposerInformation|\PHPUnit_Framework_MockObject_MockObject - */ - private $composerInformationMock; - /** * Model * @@ -29,50 +23,28 @@ class TypeMapperTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->composerInformationMock = $this->getMockBuilder(ComposerInformation::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->typeMapperMock = $this->getMockBuilder(TypeMapper::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->model = new TypeMapper( - $this->composerInformationMock - ); + $this->model = new TypeMapper(); } /** - * @param string $packageName * @param string $packageType * @param string $expected * @dataProvider mapDataProvider */ - public function testMap($packageName, $packageType, $expected) + public function testMap($packageType, $expected) { - $rootPackageMock = $this->getMock(RootPackageInterface::class); - $rootPackageMock->expects(static::once()) - ->method('getRequires') - ->willReturn( - ['magento/sample-module-one' => ''] - ); - - $this->composerInformationMock->expects(static::once()) - ->method('getRootPackage') - ->willReturn($rootPackageMock); - static::assertEquals( $expected, - $this->model->map($packageName, $packageType) + $this->model->map($packageType) ); } public function mapDataProvider() { return [ - ['magento/sample-module-one', ComposerInformation::MODULE_PACKAGE_TYPE, TypeMapper::EXTENSION_PACKAGE_TYPE], - ['magento/sample-module-two', ComposerInformation::MODULE_PACKAGE_TYPE, 'Module'], - ['magento/sample-module-two', 'undefined', TypeMapper::UNDEFINED_PACKAGE_TYPE] + [ComposerInformation::THEME_PACKAGE_TYPE, TypeMapper::THEME_PACKAGE_TYPE], + [ComposerInformation::MODULE_PACKAGE_TYPE, TypeMapper::MODULE_PACKAGE_TYPE], + ['undefined', TypeMapper::UNDEFINED_PACKAGE_TYPE] ]; } } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php index 3cb9a1617ec..74d5647a9b2 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php @@ -10,6 +10,7 @@ use Composer\Package\RootPackage; use Magento\Framework\Composer\ComposerInformation; use Magento\Setup\Model\PackagesData; use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Magento\Setup\Model\Grid\TypeMapper; /** * Tests Magento\Setup\Model\PackagesData @@ -116,12 +117,23 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase . '}}}' ); + $typeMapper = $this->getMockBuilder(TypeMapper::class) + ->disableOriginalConstructor() + ->getMock(); + $typeMapper->expects(static::any()) + ->method('map') + ->willReturnMap([ + [ComposerInformation::MODULE_PACKAGE_TYPE, TypeMapper::MODULE_PACKAGE_TYPE], + ]); + + $this->packagesData = new PackagesData( $this->composerInformation, $timeZoneProvider, $packagesAuth, $filesystem, - $objectManagerProvider + $objectManagerProvider, + $typeMapper ); } @@ -166,11 +178,17 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase ); } - public function testGetPackageExtraInfo() + public function testAddPackageExtraInfo() { static::assertEquals( - ['x-magento-ext-title' => 'Package 3 title', 'x-magento-ext-type' => 'Extension'], - $this->packagesData->getPackageExtraInfo('magento/package-3', '1.0.2') + [ + 'package_title' => 'Package 3 title', + 'package_type' => 'Extension', + 'name' => 'magento/package-3', + 'version' => '1.0.2', + 'package_link' => '' + ], + $this->packagesData->addPackageExtraInfo(['name' => 'magento/package-3', 'version' => '1.0.2']) ); } } diff --git a/setup/view/magento/setup/extension-grid.phtml b/setup/view/magento/setup/extension-grid.phtml index fc6129ae7f7..2cfff417e0f 100644 --- a/setup/view/magento/setup/extension-grid.phtml +++ b/setup/view/magento/setup/extension-grid.phtml @@ -130,10 +130,10 @@ data-label="{{getIndicatorInfo(extension, 'label')}}" ><span>{{getIndicatorInfo(extension, 'label')}}</span> </span> - <span class="data-grid-data">{{extension.product_name}}</span> + <span class="data-grid-data">{{extension.package_title}}</span> </td> <td> - <span class="data-grid-data">{{extension.type}}</span> + <span class="data-grid-data">{{extension.package_type}}</span> </td> <td> <span class="data-grid-data" data-type="version">{{extension.version}}</span> diff --git a/setup/view/magento/setup/install-extension-grid.phtml b/setup/view/magento/setup/install-extension-grid.phtml index 27a3a893cfd..1ddcb267ebc 100644 --- a/setup/view/magento/setup/install-extension-grid.phtml +++ b/setup/view/magento/setup/install-extension-grid.phtml @@ -96,10 +96,10 @@ </label> </td> <td> - <span class="data-grid-data">{{extension.product_name}}</span> + <span class="data-grid-data">{{extension.package_title}}</span> </td> <td> - <span class="data-grid-data">{{extension.type}}</span> + <span class="data-grid-data">{{extension.package_type}}</span> </td> <td> <span class="data-grid-data">{{extension.vendor}}</span> @@ -112,9 +112,9 @@ </select> </span> <span class="component-indicator _tooltip" - ng-show="extension.link" + ng-show="extension.package_link" data-label="View info on Marketplace" - ><a href="{{extension.link}}" target="_blank"></a> + ><a href="{{extension.package_link}}" target="_blank"></a> </span> </td> <td class="data-grid-data"> diff --git a/setup/view/magento/setup/module-grid.phtml b/setup/view/magento/setup/module-grid.phtml index b310aef76c9..6f9100d4234 100644 --- a/setup/view/magento/setup/module-grid.phtml +++ b/setup/view/magento/setup/module-grid.phtml @@ -78,7 +78,7 @@ ng-class="{'_show-dependencies': item.requiredBy.length > 0 && showDependencies, '_hide-dependencies': item.requiredBy.length > 0 && !showDependencies, '_no-dependencies': item.requiredBy.length == 0}"> - {{item.product_name}} + {{item.package_title}} </div> <div class="product-modules-block" ng-show="item.requiredBy.length > 0 && showDependencies"> <div class="product-modules-title"> @@ -94,7 +94,7 @@ data-label="{{getIndicatorInfo(product, 'label')}}"> <span>{{getIndicatorInfo(product, 'label')}}</span> </span> - {{product.product_name}} + {{product.package_title}} </li> </ul> </div> @@ -110,7 +110,7 @@ </div> <ul class="product-modules-list"> <li ng-repeat="product in item.requiredBy"> - {{product.type}} + {{product.package_type}} </li> </ul> </div> diff --git a/setup/view/magento/setup/update-extension-grid.phtml b/setup/view/magento/setup/update-extension-grid.phtml index e308a63b048..b427ef24923 100644 --- a/setup/view/magento/setup/update-extension-grid.phtml +++ b/setup/view/magento/setup/update-extension-grid.phtml @@ -59,10 +59,10 @@ | startFrom:(currentPage - 1) * rowLimit | limitTo:rowLimit" > <td> - <span class="data-grid-data">{{extension.product_name}}</span> + <span class="data-grid-data">{{extension.package_title}}</span> </td> <td> - <span class="data-grid-data">{{extension.type}}</span> + <span class="data-grid-data">{{extension.package_type}}</span> </td> <td> <span class="data-grid-data">{{extension.vendor}}</span> @@ -79,9 +79,9 @@ </select> </span> <span class="component-indicator _tooltip" - ng-show="extension.link" + ng-show="extension.package_link" data-label="View info on Marketplace" - ><a href="{{extension.link}}" target="_blank"></a> + ><a href="{{extension.package_link}}" target="_blank"></a> </span> </td> <td class="data-grid-data"> -- GitLab From 5742369bf515f2a76361d8305e5e0c0a6b864b42 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Mon, 15 Aug 2016 18:12:22 +0300 Subject: [PATCH 363/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface - test fix --- app/code/Magento/Sales/Model/OrderInvoice.php | 16 +++++----- .../Test/Unit/Model/OrderInvoiceTest.php | 31 ++++++++++++++++--- app/code/Magento/Sales/etc/di.xml | 2 -- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Sales/Model/OrderInvoice.php b/app/code/Magento/Sales/Model/OrderInvoice.php index e8cb28fca11..12d1e74d150 100644 --- a/app/code/Magento/Sales/Model/OrderInvoice.php +++ b/app/code/Magento/Sales/Model/OrderInvoice.php @@ -12,15 +12,15 @@ use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface; use Magento\Sales\Api\OrderInvoiceInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order\Config as OrderConfig; -use Magento\Sales\Model\Order\Invoice\InvoiceValidator; +use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface; use Magento\Sales\Model\Order\Invoice\NotifierInterface; use Magento\Sales\Model\Order\InvoiceDocumentFactory; use Magento\Sales\Model\Order\InvoiceQuantityValidator; use Magento\Sales\Model\Order\InvoiceRepository; use Magento\Sales\Model\Order\OrderStateResolverInterface; +use Magento\Sales\Model\Order\OrderValidatorInterface; use Magento\Sales\Model\Order\PaymentAdapterInterface; use Magento\Sales\Model\Order\Validation\CanInvoice; -use Magento\Sales\Model\Order\OrderValidator; use Psr\Log\LoggerInterface; /** @@ -45,7 +45,7 @@ class OrderInvoice implements OrderInvoiceInterface private $invoiceDocumentFactory; /** - * @var InvoiceValidator + * @var InvoiceValidatorInterface */ private $invoiceValidator; @@ -80,7 +80,7 @@ class OrderInvoice implements OrderInvoiceInterface private $logger; /** - * @var OrderValidator + * @var OrderValidatorInterface */ private $orderValidator; @@ -89,8 +89,8 @@ class OrderInvoice implements OrderInvoiceInterface * @param ResourceConnection $resourceConnection * @param OrderRepositoryInterface $orderRepository * @param InvoiceDocumentFactory $invoiceDocumentFactory - * @param InvoiceValidator $invoiceValidator - * @param OrderValidator $orderValidator + * @param InvoiceValidatorInterface $invoiceValidator + * @param OrderValidatorInterface $orderValidator * @param PaymentAdapterInterface $paymentAdapter * @param OrderStateResolverInterface $orderStateResolver * @param OrderConfig $config @@ -103,8 +103,8 @@ class OrderInvoice implements OrderInvoiceInterface ResourceConnection $resourceConnection, OrderRepositoryInterface $orderRepository, InvoiceDocumentFactory $invoiceDocumentFactory, - InvoiceValidator $invoiceValidator, - OrderValidator $orderValidator, + InvoiceValidatorInterface $invoiceValidator, + OrderValidatorInterface $orderValidator, PaymentAdapterInterface $paymentAdapter, OrderStateResolverInterface $orderStateResolver, OrderConfig $config, diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php index bc36da112aa..e0356505932 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/OrderInvoiceTest.php @@ -14,11 +14,12 @@ use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order; use Magento\Sales\Model\Order\Config as OrderConfig; +use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface; use Magento\Sales\Model\Order\Invoice\NotifierInterface; use Magento\Sales\Model\Order\InvoiceDocumentFactory; use Magento\Sales\Model\Order\InvoiceRepository; -use Magento\Sales\Model\Order\InvoiceValidatorInterface; use Magento\Sales\Model\Order\OrderStateResolverInterface; +use Magento\Sales\Model\Order\OrderValidatorInterface; use Magento\Sales\Model\Order\PaymentAdapterInterface; use Magento\Sales\Model\OrderInvoice; use Psr\Log\LoggerInterface; @@ -50,6 +51,11 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase */ private $invoiceValidatorMock; + /** + * @var OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderValidatorMock; + /** * @var PaymentAdapterInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -128,6 +134,10 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->orderValidatorMock = $this->getMockBuilder(OrderValidatorInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->paymentAdapterMock = $this->getMockBuilder(PaymentAdapterInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -177,6 +187,7 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase $this->orderRepositoryMock, $this->invoiceDocumentFactoryMock, $this->invoiceValidatorMock, + $this->orderValidatorMock, $this->paymentAdapterMock, $this->orderStateResolverMock, $this->configMock, @@ -212,7 +223,11 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase $this->invoiceValidatorMock->expects($this->once()) ->method('validate') - ->with($this->invoiceMock, $this->orderMock) + ->with($this->invoiceMock) + ->willReturn([]); + $this->orderValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->orderMock) ->willReturn([]); $this->paymentAdapterMock->expects($this->once()) @@ -311,8 +326,12 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase $this->invoiceValidatorMock->expects($this->once()) ->method('validate') - ->with($this->invoiceMock, $this->orderMock) + ->with($this->invoiceMock) ->willReturn($errorMessages); + $this->orderValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->orderMock) + ->willReturn([]); $this->orderInvoice->execute( $orderId, @@ -356,7 +375,11 @@ class OrderInvoiceTest extends \PHPUnit_Framework_TestCase $this->invoiceValidatorMock->expects($this->once()) ->method('validate') - ->with($this->invoiceMock, $this->orderMock) + ->with($this->invoiceMock) + ->willReturn([]); + $this->orderValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->orderMock) ->willReturn([]); $e = new \Exception(); diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 00dbb0b4226..5ee1fb73e1b 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -69,8 +69,6 @@ <preference for="Magento\Sales\Api\ShipmentTrackRepositoryInterface" type="Magento\Sales\Api\Data\ShipmentTrack\Repository"/> <preference for="Magento\Sales\Api\TransactionRepositoryInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Repository"/> <preference for="Magento\Sales\Model\Order\Invoice\NotifierInterface" type="Magento\Sales\Model\Order\Invoice\Notifier"/> - <preference for="Magento\Sales\Model\Order\InvoiceValidatorInterface" type="Magento\Sales\Model\Order\InvoiceValidator"/> - <preference for="Magento\Sales\Model\Order\OrderValidatorInterface" type="Magento\Sales\Model\Order\OrderValidator"/> <preference for="Magento\Sales\Model\Order\PaymentAdapterInterface" type="Magento\Sales\Model\Order\PaymentAdapter"/> <preference for="Magento\Sales\Model\Order\Payment\Transaction\ManagerInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Manager"/> <preference for="Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Builder"/> -- GitLab From 6fea1161ddcc8451e55a3497be20bf6f95392690 Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Mon, 15 Aug 2016 18:56:47 +0300 Subject: [PATCH 364/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Message/Multishipping/Plugin/ItemsBox.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php b/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php index e79052a1fb3..fc0b1caebef 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php +++ b/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php @@ -5,6 +5,10 @@ */ namespace Magento\GiftMessage\Block\Message\Multishipping\Plugin; +use Magento\Multishipping\Block\Checkout\Shipping; +use Magento\GiftMessage\Helper\Message as HelperMessage; +use Magento\Framework\DataObject; + /** * Multishipping items box plugin */ @@ -13,16 +17,16 @@ class ItemsBox /** * Gift message helper * - * @var \Magento\GiftMessage\Helper\Message + * @var HelperMessage */ protected $helper; /** * Construct * - * @param \Magento\GiftMessage\Helper\Message $helper + * @param HelperMessage $helper */ - public function __construct(\Magento\GiftMessage\Helper\Message $helper) + public function __construct(HelperMessage $helper) { $this->helper = $helper; } @@ -30,19 +34,15 @@ class ItemsBox /** * Get items box message text for multishipping * - * @param \Magento\Multishipping\Block\Checkout\Shipping $subject - * @param callable $proceed - * @param \Magento\Framework\DataObject $addressEntity + * @param Shipping $subject + * @param string $itemsBoxText + * @param DataObject $addressEntity * * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundGetItemsBoxTextAfter( - \Magento\Multishipping\Block\Checkout\Shipping $subject, - \Closure $proceed, - \Magento\Framework\DataObject $addressEntity - ) { - $itemsBoxText = $proceed($addressEntity); + public function afterGetItemsBoxTextAfter(Shipping $subject, $itemsBoxText, DataObject $addressEntity) + { return $itemsBoxText . $this->helper->getInline('multishipping_address', $addressEntity); } } -- GitLab From a5146f523faca488e0927392b8f176ac3739366a Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Mon, 15 Aug 2016 18:58:07 +0300 Subject: [PATCH 365/838] MAGETWO-55193: Extension Management with Marketplace data - CR fixes --- .../src/Magento/Setup/Model/PackagesData.php | 1 + .../Test/Unit/Model/PackagesDataTest.php | 84 ++++++++++--------- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index 52334ba5582..20fac85e822 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -419,6 +419,7 @@ class PackagesData } /** + * Get MetaPackage for package * * @param array $packages * @return array diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php index 74d5647a9b2..5a7ead38466 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PackagesDataTest.php @@ -10,7 +10,6 @@ use Composer\Package\RootPackage; use Magento\Framework\Composer\ComposerInformation; use Magento\Setup\Model\PackagesData; use PHPUnit_Framework_MockObject_MockObject as MockObject; -use Magento\Setup\Model\Grid\TypeMapper; /** * Tests Magento\Setup\Model\PackagesData @@ -23,44 +22,9 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase */ private $packagesData; - /** - * @var ComposerInformation|MockObject - */ - private $composerInformation; - public function setUp() { - $this->composerInformation = $this->getMock(ComposerInformation::class, [], [], '', false); - $this->composerInformation->expects($this->any())->method('getInstalledMagentoPackages')->willReturn( - [ - 'magento/package-1' => [ - 'name' => 'magento/package-1', - 'type' => 'magento2-module', - 'version'=> '1.0.0' - ], - 'magento/package-2' => [ - 'name' => 'magento/package-2', - 'type' => 'magento2-module', - 'version'=> '1.0.1' - ] - ] - ); - - $this->composerInformation->expects($this->any())->method('getRootRepositories') - ->willReturn(['repo1', 'repo2']); - $this->composerInformation->expects($this->any())->method('getPackagesTypes') - ->willReturn(['magento2-module']); - $rootPackage = $this->getMock(RootPackage::class, [], ['magento/project', '2.1.0', '2']); - $rootPackage->expects($this->any()) - ->method('getRequires') - ->willReturn([ - 'magento/package-1' => '1.0.0', - 'magento/package-2' => '1.0.1' - ]); - $this->composerInformation - ->expects($this->any()) - ->method('getRootPackage') - ->willReturn($rootPackage); + $composerInformation = $this->getComposerInformation(); $timeZoneProvider = $this->getMock(\Magento\Setup\Model\DateTime\TimeZoneProvider::class, [], [], '', false); $timeZone = $this->getMock(\Magento\Framework\Stdlib\DateTime\Timezone::class, [], [], '', false); $timeZoneProvider->expects($this->any())->method('get')->willReturn($timeZone); @@ -117,18 +81,17 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase . '}}}' ); - $typeMapper = $this->getMockBuilder(TypeMapper::class) + $typeMapper = $this->getMockBuilder(\Magento\Setup\Model\Grid\TypeMapper::class) ->disableOriginalConstructor() ->getMock(); $typeMapper->expects(static::any()) ->method('map') ->willReturnMap([ - [ComposerInformation::MODULE_PACKAGE_TYPE, TypeMapper::MODULE_PACKAGE_TYPE], + [ComposerInformation::MODULE_PACKAGE_TYPE, \Magento\Setup\Model\Grid\TypeMapper::MODULE_PACKAGE_TYPE], ]); - $this->packagesData = new PackagesData( - $this->composerInformation, + $composerInformation, $timeZoneProvider, $packagesAuth, $filesystem, @@ -137,6 +100,45 @@ class PackagesDataTest extends \PHPUnit_Framework_TestCase ); } + /** + * @return ComposerInformation|MockObject + */ + private function getComposerInformation() + { + $composerInformation = $this->getMock(ComposerInformation::class, [], [], '', false); + $composerInformation->expects($this->any())->method('getInstalledMagentoPackages')->willReturn( + [ + 'magento/package-1' => [ + 'name' => 'magento/package-1', + 'type' => 'magento2-module', + 'version'=> '1.0.0' + ], + 'magento/package-2' => [ + 'name' => 'magento/package-2', + 'type' => 'magento2-module', + 'version'=> '1.0.1' + ] + ] + ); + + $composerInformation->expects($this->any())->method('getRootRepositories') + ->willReturn(['repo1', 'repo2']); + $composerInformation->expects($this->any())->method('getPackagesTypes') + ->willReturn(['magento2-module']); + $rootPackage = $this->getMock(RootPackage::class, [], ['magento/project', '2.1.0', '2']); + $rootPackage->expects($this->any()) + ->method('getRequires') + ->willReturn([ + 'magento/package-1' => '1.0.0', + 'magento/package-2' => '1.0.1' + ]); + $composerInformation->expects($this->any()) + ->method('getRootPackage') + ->willReturn($rootPackage); + + return $composerInformation; + } + public function testSyncPackagesData() { $latestData = $this->packagesData->syncPackagesData(); -- GitLab From 9a465f7f9d91b9a1828dd2cfe55903d09751a2ba Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 15 Aug 2016 16:57:19 -0500 Subject: [PATCH 366/838] MAGETWO-55186: Eliminate @escapeNotVerified in Wishlist Module --- .../Block/Customer/Wishlist/Item/Options.php | 14 +++++++++----- .../Block/Customer/Wishlist/Item/OptionsTest.php | 4 ++-- .../view/frontend/templates/options_list.phtml | 4 ++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php index 07bb2e7708d..850dfa074ca 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist/Item/Options.php @@ -106,12 +106,16 @@ class Options extends \Magento\Wishlist\Block\AbstractBlock $options = $helper->getOptions($item); foreach ($options as $index => $option) { if (is_array($option) && array_key_exists('value', $option)) { - if (is_array($option['value'])) { - $option['value'] = nl2br(implode("\n", $option['value'])); - } - if (!(array_key_exists('has_html', $option) && $option['has_html'] === true)) { - $option['value'] = $this->escapeHtml($option['value']); + if (is_array($option['value'])) { + foreach ($option['value'] as $key => $value) { + $option['value'][$key] = $this->escapeHtml($value); + } + + } else { + $option['value'] = $this->escapeHtml($option['value']); + } + } $options[$index]['value'] = $option['value']; } diff --git a/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php b/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php index 37d44e0e047..3742a0b1dc6 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Block/Customer/Wishlist/Item/OptionsTest.php @@ -131,11 +131,11 @@ class OptionsTest extends \PHPUnit_Framework_TestCase [ [ 'label' => 'title', - 'value' => '1 x name <span class="price">$15.00</span>', + 'value' => ['1 x name <span class="price">$15.00</span>'], 'has_html' => true, ], ['label' => 'title', 'value' => 'value'], - ['label' => 'title', 'value' => 'value'], + ['label' => 'title', 'value' => ['value']], ], ] ]; diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index 7a761e1b3d2..8f1b5b3898d 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -19,7 +19,11 @@ <?php foreach ($options as $option): ?> <dt class="label"><?php echo $block->escapeHtml($option['label']) ?></dt> <dd class="values"> + <?php if (is_array($option['value'])): ?> + <?php /* @noEscape */ echo nl2br(implode("\n", $option['value'])) ?> + <?php else: ?> <?php /* @noEscape */ echo $option['value'] ?> + <?php endif; ?> </dd> <?php endforeach; ?> </dl> -- GitLab From 821e2dc1bc981a51eab8e4cd22435395b0b54618 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 15 Aug 2016 17:45:48 -0500 Subject: [PATCH 367/838] MAGETWO-50123: Login failed after new custom attribute was added - removing SelectBackend class and fixing the problem from the javascript side by ensuring that select is posted even on empty value --- .../Product/Form/Modifier/Eav.php | 6 ++--- .../Magento/Eav/Model/Entity/Attribute.php | 9 -------- .../Attribute/Backend/SelectBackend.php | 22 ------------------- .../view/base/web/js/form/element/select.js | 6 ++++- 4 files changed, 8 insertions(+), 35 deletions(-) delete mode 100644 app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index 83d2f007031..a17acb4dea1 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -523,11 +523,11 @@ class Eav extends AbstractModifier } /** - * Check is product already exists or we trying to create one + * Check is product already new or we trying to create one * * @return bool */ - private function isProductExists() + private function isProductNew() { return (bool) $this->locator->getProduct()->getId(); } @@ -552,7 +552,7 @@ class Eav extends AbstractModifier */ private function isShowDefaultValue(ProductAttributeInterface $attribute) { - if (!$this->isProductExists()) { + if (!$this->isProductNew()) { return true; } elseif ($attribute->getIsRequired() && !$this->isProductHasValueForAttribute($attribute)) { return true; diff --git a/app/code/Magento/Eav/Model/Entity/Attribute.php b/app/code/Magento/Eav/Model/Entity/Attribute.php index 79b1089538e..528dee5f239 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute.php @@ -167,15 +167,6 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute im break; } - // we should override default behaviour of Magento\Framework\Exception\LocalizedException\AbstractBackend - // but can't do this in abstract model and can't update DB records because of backward compatibility - if ($this->getFrontendInput() == 'select' - && !$this->getIsRequired() - && !$this->getBackendModel() - ) { - return \Magento\Eav\Model\Entity\Attribute\Backend\SelectBackend::class; - } - return parent::_getDefaultBackendModel(); } diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php b/app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php deleted file mode 100644 index f6fb9fb1b76..00000000000 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Backend/SelectBackend.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Eav\Model\Entity\Attribute\Backend; - -/** - * Entity/Attribute/Model - attribute backend default - * - * @author Magento Core Team <core@magentocommerce.com> - */ -class SelectBackend extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend -{ - - public function beforeSave($object) - { - return $this; - - } -} - diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/select.js b/app/code/Magento/Ui/view/base/web/js/form/element/select.js index ebcbd967895..ef869965e35 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/select.js @@ -163,6 +163,10 @@ define([ this.observe('options') .setOptions(this.options()); + if (_.isUndefined(this.value()) && !this.default) { + this.clear(); + } + return this; }, @@ -194,7 +198,7 @@ define([ }, /** - * Matches specfied value with existing options + * Matches specified value with existing options * or, if value is not specified, returns value of the first option. * * @returns {*} -- GitLab From 93772a35cfad14a87064b81ad2f7c6968edbe579 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Mon, 15 Aug 2016 17:51:32 -0500 Subject: [PATCH 368/838] MAGETWO-52905: Group product not found by weight using advanced search - fixed mysql join condition --- .../CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 8c30ff7902a..05205f04f8b 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Filter/Preprocessor.php @@ -179,14 +179,14 @@ class Preprocessor implements PreprocessorInterface $tableSuffix = $attribute->getBackendType() === 'decimal' ? '_decimal' : ''; $table = $this->resource->getTableName("catalog_product_index_eav{$tableSuffix}"); $select = $this->connection->select(); - $linkIdField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField(); + $entityField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getIdentifierField(); $currentStoreId = $this->scopeResolver->getScope()->getId(); $select->from(['e' => $this->resource->getTableName('catalog_product_entity')], ['entity_id']) ->join( ['main_table' => $table], - "main_table.{$linkIdField} = e.{$linkIdField}", + "main_table.{$entityField} = e.{$entityField}", [] ) ->columns([$filter->getField() => 'main_table.value']) -- GitLab From e0575d6ea366c4aa9a4fa8acc0c8fb04ddb01e91 Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Tue, 16 Aug 2016 10:54:08 +0300 Subject: [PATCH 369/838] MAGETWO-55953: Exception occurs when tracking shipment with invalid FedEx tracking number - Get rid of 'enterprise' keyword --- app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl b/app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl index 3771c1e6978..77f53e02a53 100644 --- a/app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl +++ b/app/code/Magento/Fedex/etc/wsdl/TrackService_v10.wsdl @@ -185,11 +185,7 @@ <xs:element name="CountryOfManufacture" type="xs:string" minOccurs="0"/> <xs:element name="HarmonizedCode" type="xs:string" minOccurs="0"/> <xs:element name="Weight" type="ns:Weight" minOccurs="0"/> - <xs:element name="Quantity" type="xs:decimal" minOccurs="0"> - <xs:annotation> - <xs:documentation>This field is used for enterprise transactions.</xs:documentation> - </xs:annotation> - </xs:element> + <xs:element name="Quantity" type="xs:decimal" minOccurs="0"/> <xs:element name="QuantityUnits" type="xs:string" minOccurs="0"/> <xs:element name="AdditionalMeasures" type="ns:Measure" minOccurs="0" maxOccurs="unbounded"> <xs:annotation> -- GitLab From 7051bfb1d3710c7f7122a1f8b35ddf86c626e656 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Tue, 16 Aug 2016 10:59:30 +0300 Subject: [PATCH 370/838] MAGETWO-56492: Implement ShipmentDocumentFactory --- .../Magento/Sales/Model/Order/Shipment.php | 2 +- .../Model/Order/ShipmentDocumentFactory.php | 83 +++++++++++++++++++ .../Order/ShipmentDocumentFactoryTest.php | 79 ++++++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php create mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php index 6647bae750f..2277f92d6e0 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment.php @@ -405,7 +405,7 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa * Adds comment to shipment with additional possibility to send it to customer via email * and show it in customer account * - * @param \Magento\Sales\Model\Order\Shipment\Comment $comment + * @param \Magento\Sales\Model\Order\Shipment\Comment|string $comment * @param bool $notify * @param bool $visibleOnFront * @return $this diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php new file mode 100644 index 00000000000..6509aacd932 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Model\Order; + +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; +use Magento\Sales\Api\Data\ShipmentCommentInterface; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentItemCreationInterface; +use Magento\Sales\Api\Data\ShipmentPackageInterface; +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; + +/** + * Class InvoiceDocumentFactory + * + * @api + */ +class ShipmentDocumentFactory +{ + private $shipmentFactory; + + public function __construct( + ShipmentFactory $shipmentFactory + ) { + $this->shipmentFactory = $shipmentFactory; + } + + /** + * @param OrderInterface $order + * @param array $items + * @param array $tracks + * @param ShipmentCommentCreationInterface|null $comment + * @param bool $appendComment + * @param array $packages + * @return Shipment + */ + public function create( + OrderInterface $order, + $items = [], + $tracks = [], + ShipmentCommentCreationInterface $comment = null, + $appendComment = false, + $packages = [] + ) { + + $shipmentItems = $this->itemsToArray($items); + /** @var Shipment $shipment */ + $shipment = $this->shipmentFactory->create( + $order, + $shipmentItems, + $tracks + ); + + if ($comment) { + $shipment->addComment( + $comment->getComment(), + $appendComment, + $comment->getIsVisibleOnFront() + ); + } + + return $shipment; + } + + /** + * Convert Items To Array + * + * @param InvoiceItemCreationInterface[] $items + * @return array + */ + private function itemsToArray($items = []) + { + $invoiceItems = []; + foreach ($items as $item) { + $invoiceItems[$item->getOrderItemId()] = $item->getQty(); + } + return $invoiceItems; + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php new file mode 100644 index 00000000000..a3ee72ab318 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -0,0 +1,79 @@ +<?php + +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Order; + +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; +use Magento\Sales\Api\Data\ShipmentItemCreationInterface; +use Magento\Sales\Model\Order\ShipmentFactory; +use Magento\Sales\Model\Order\ShipmentDocumentFactory; +use Magento\Sales\Model\Order; + +/** + * Class InvoiceDocumentFactoryTest + */ +class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject|ShipmentFactory + */ + private $shipmentFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|Order + */ + private $orderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|ShipmentItemCreationInterface + */ + private $itemMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|ShipmentCommentCreationInterface + */ + private $commentMock; + + /** + * @var ShipmentDocumentFactory + */ + private $invoiceDocumentFactory; + + protected function setUp() + { + $this->shipmentFactoryMock = $this->getMockBuilder(ShipmentFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->orderMock = $this->getMockBuilder(Order::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->itemMock = $this->getMockBuilder(ShipmentItemCreationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->commentMock = $this->getMockBuilder(ShipmentCommentCreationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->invoiceDocumentFactory = new ShipmentDocumentFactory($this->shipmentFactoryMock); + } + + public function testCreate() + { + $tracks = ["1234567890"]; + $appendComment = true; + $packages = []; + $this->invoiceDocumentFactory->create( + $this->orderMock, + $this->itemMock, + $this->commentMock, + $appendComment, + $packages + ); + } +} -- GitLab From fc52177d869f4c4574b608590dbae2b727035638 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 11:00:18 +0300 Subject: [PATCH 371/838] MAGETWO-56494: Introduce and implement ShipmentValidatorInterface - test fix --- app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php index 4fed2a56cc3..cbb68edaa8a 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidator.php @@ -10,7 +10,7 @@ use Magento\Sales\Api\Data\InvoiceInterface; /** * Class InvoiceValidatorRunner */ -class InvoiceValidator +class InvoiceValidator implements InvoiceValidatorInterface { /** * @var \Magento\Sales\Model\Validator -- GitLab From 67210ad24f8a6ae7dc5e8604e0f3c052530d1942 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Tue, 16 Aug 2016 11:18:03 +0300 Subject: [PATCH 372/838] MAGETWO-56778: Value for multiple select attribute does not save --- app/code/Magento/Eav/Model/Entity/AttributeLoader.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index adc8e56e4ba..af6b88fe089 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -62,6 +62,7 @@ class AttributeLoader implements AttributeLoaderInterface * @return AbstractEntity * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function loadAllAttributes(AbstractEntity $resource, DataObject $object = null) { -- GitLab From 74aaf3e479b0ca61345e13da9941bb5d9f35e1c6 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Tue, 16 Aug 2016 11:59:31 +0300 Subject: [PATCH 373/838] MAGETWO-56492: Implement ShipmentDocumentFactory --- .../Order/ShipmentDocumentFactoryTest.php | 64 +++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php index a3ee72ab318..30ae7101209 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -11,6 +11,7 @@ use Magento\Sales\Api\Data\ShipmentItemCreationInterface; use Magento\Sales\Model\Order\ShipmentFactory; use Magento\Sales\Model\Order\ShipmentDocumentFactory; use Magento\Sales\Model\Order; +use Magento\Sales\Api\Data\ShipmentInterface; /** * Class InvoiceDocumentFactoryTest @@ -37,6 +38,11 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase */ private $commentMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|ShipmentInterface + */ + private $shipmentMock; + /** * @var ShipmentDocumentFactory */ @@ -60,6 +66,12 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); + $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class) + ->disableOriginalConstructor() + ->setMethods(['addComment']) + ->getMockForAbstractClass(); + + $this->invoiceDocumentFactory = new ShipmentDocumentFactory($this->shipmentFactoryMock); } @@ -68,12 +80,52 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase $tracks = ["1234567890"]; $appendComment = true; $packages = []; - $this->invoiceDocumentFactory->create( - $this->orderMock, - $this->itemMock, - $this->commentMock, - $appendComment, - $packages + $items = [1 => 10]; + + $this->itemMock->expects($this->once()) + ->method('getOrderItemId') + ->willReturn(1); + + $this->itemMock->expects($this->once()) + ->method('getQty') + ->willReturn(10); + + $this->shipmentFactoryMock->expects($this->once()) + ->method('create') + ->with( + $this->orderMock, + $items, + $tracks + ) + ->willReturn($this->shipmentMock); + + if ($appendComment) { + $comment = "New comment!"; + $visibleOnFront = true; + $this->commentMock->expects($this->once()) + ->method('getComment') + ->willReturn($comment); + + $this->commentMock->expects($this->once()) + ->method('getIsVisibleOnFront') + ->willReturn($visibleOnFront); + + $this->shipmentMock->expects($this->once()) + ->method('addComment') + ->with($comment, $appendComment, $visibleOnFront) + ->willReturnSelf(); + } + + $this->assertEquals( + $this->invoiceDocumentFactory->create( + $this->orderMock, + [$this->itemMock], + $tracks, + $this->commentMock, + $appendComment, + $packages + ), + $this->shipmentMock ); } } -- GitLab From 281b7a5e8c68ddc7adf27e2e6b97150f200add28 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Tue, 16 Aug 2016 12:25:16 +0300 Subject: [PATCH 374/838] MAGETWO-55193: Extension Management with Marketplace data - Update message on Readiness Check --- setup/pub/magento/setup/extension-grid.js | 4 ++-- setup/pub/magento/setup/install-extension-grid.js | 1 + setup/pub/magento/setup/main.js | 12 +++++++++--- setup/pub/magento/setup/module-grid.js | 2 +- setup/pub/magento/setup/readiness-check.js | 10 +++++++++- setup/pub/magento/setup/update-extension-grid.js | 2 +- setup/src/Magento/Setup/Model/PackagesData.php | 1 + .../magento/setup/readiness-check/progress.phtml | 2 +- 8 files changed, 25 insertions(+), 9 deletions(-) diff --git a/setup/pub/magento/setup/extension-grid.js b/setup/pub/magento/setup/extension-grid.js index 255547cb5f7..e5fc525dbd1 100644 --- a/setup/pub/magento/setup/extension-grid.js +++ b/setup/pub/magento/setup/extension-grid.js @@ -129,7 +129,7 @@ angular.module('extension-grid', ['ngStorage']) version: $scope.availableUpdatePackages[extension.name]['latestVersion'] } ]; - titleService.setTitle('update', extension.moduleName ? extension.moduleName : extension.name); + titleService.setTitle('update', extension); $state.go('root.readiness-check-update'); }; @@ -139,7 +139,7 @@ angular.module('extension-grid', ['ngStorage']) name: extension.name } ]; - titleService.setTitle('uninstall', extension.moduleName ? extension.moduleName : extension.name); + titleService.setTitle('uninstall', extension); $localStorage.componentType = extension.type; $state.go('root.readiness-check-uninstall'); }; diff --git a/setup/pub/magento/setup/install-extension-grid.js b/setup/pub/magento/setup/install-extension-grid.js index f4ed97baae3..f749e7eb284 100644 --- a/setup/pub/magento/setup/install-extension-grid.js +++ b/setup/pub/magento/setup/install-extension-grid.js @@ -138,6 +138,7 @@ angular.module('install-extension-grid', ['ngStorage', 'clickOut']) } ]; $localStorage.moduleName = extension.name; + $localStorage.packageTitle = extension.package_title; $scope.error = false; $scope.errorMessage = ''; } diff --git a/setup/pub/magento/setup/main.js b/setup/pub/magento/setup/main.js index b62d03f990f..4227f4801df 100644 --- a/setup/pub/magento/setup/main.js +++ b/setup/pub/magento/setup/main.js @@ -251,13 +251,19 @@ main.controller('navigationController', .service('titleService', ['$localStorage', '$rootScope', function ($localStorage, $rootScope) { return { - setTitle: function(type, moduleName) { - $localStorage.moduleName = moduleName; + setTitle: function(type, component) { + if (type === 'enable' || type === 'disable') { + $localStorage.packageTitle = $localStorage.moduleName = component.moduleName; + } else { + $localStorage.moduleName = component.moduleName ? component.moduleName : component.name; + $localStorage.packageTitle = component.package_title; + } + if (typeof $localStorage.titles === 'undefined') { $localStorage.titles = []; } $localStorage.titles[type] = type.charAt(0).toUpperCase() + type.slice(1) + ' ' - + $localStorage.moduleName; + + ($localStorage.packageTitle ? $localStorage.packageTitle : $localStorage.moduleName); $rootScope.titles = $localStorage.titles; } }; diff --git a/setup/pub/magento/setup/module-grid.js b/setup/pub/magento/setup/module-grid.js index 7b9f53ddcf2..21dec8795f1 100644 --- a/setup/pub/magento/setup/module-grid.js +++ b/setup/pub/magento/setup/module-grid.js @@ -66,7 +66,7 @@ angular.module('module-grid', ['ngStorage']) isComposerPackage: component.name !== 'unknown', } ]; - titleService.setTitle(type, component.moduleName ? component.moduleName : component.name); + titleService.setTitle(type, component); $localStorage.componentType = component.type; $state.go('root.readiness-check-'+type); }; diff --git a/setup/pub/magento/setup/readiness-check.js b/setup/pub/magento/setup/readiness-check.js index 167651b0620..275d4ba6c23 100644 --- a/setup/pub/magento/setup/readiness-check.js +++ b/setup/pub/magento/setup/readiness-check.js @@ -352,7 +352,7 @@ angular.module('readiness-check', []) $scope.wordingOfReadinessCheckAction = function() { var $actionString = 'We\'re making sure your server environment is ready for '; if ($localStorage.moduleName) { - $actionString += $localStorage.moduleName; + $actionString += $localStorage.packageTitle ? $localStorage.packageTitle : $localStorage.moduleName; } else { if($state.current.type === 'install' || $state.current.type === 'upgrade') { $actionString += 'Magento'; @@ -369,6 +369,14 @@ angular.module('readiness-check', []) } else { $actionString +='ed'; } + + if ($localStorage.moduleName + && $localStorage.packageTitle + && $localStorage.moduleName != $localStorage.packageTitle + ) { + $actionString += ', which consists of the following packages:<br/>- ' + $localStorage.moduleName; + } + return $actionString; } }]); diff --git a/setup/pub/magento/setup/update-extension-grid.js b/setup/pub/magento/setup/update-extension-grid.js index f28e0aa385a..6911a84e0f1 100644 --- a/setup/pub/magento/setup/update-extension-grid.js +++ b/setup/pub/magento/setup/update-extension-grid.js @@ -39,7 +39,7 @@ angular.module('update-extension-grid', ['ngStorage', 'clickOut']) version: extension.updateVersion } ]; - titleService.setTitle('update', extension.name); + titleService.setTitle('update', extension); $scope.nextState(); }; } diff --git a/setup/src/Magento/Setup/Model/PackagesData.php b/setup/src/Magento/Setup/Model/PackagesData.php index 20fac85e822..bfab0d3c95b 100644 --- a/setup/src/Magento/Setup/Model/PackagesData.php +++ b/setup/src/Magento/Setup/Model/PackagesData.php @@ -7,6 +7,7 @@ namespace Magento\Setup\Model; /** * Class PackagesData returns system packages and available for update versions + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PackagesData { diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml index 3b7c7a38cc8..02bb243fdb6 100755 --- a/setup/view/magento/setup/readiness-check/progress.phtml +++ b/setup/view/magento/setup/readiness-check/progress.phtml @@ -30,7 +30,7 @@ <span></span><span></span><span></span><span></span> <span></span><span></span><span></span><span></span> </span> - <span class="message-text">{{wordingOfReadinessCheckAction()}}.</span> + <span class="message-text" ng-bind-html="wordingOfReadinessCheckAction()"></span> </div> </div> -- GitLab From 5bb8c1f7ac839fe081e2351cd2d39665c0f854c2 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Tue, 16 Aug 2016 12:26:43 +0300 Subject: [PATCH 375/838] MAGETWO-54458: Scope selector on product page does not display all related websites for restricted user --- app/code/Magento/Backend/Block/Store/Switcher.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Backend/Block/Store/Switcher.php b/app/code/Magento/Backend/Block/Store/Switcher.php index 2989da19b9f..eb113e45c45 100644 --- a/app/code/Magento/Backend/Block/Store/Switcher.php +++ b/app/code/Magento/Backend/Block/Store/Switcher.php @@ -152,11 +152,7 @@ class Switcher extends \Magento\Backend\Block\Template { $websites = $this->_storeManager->getWebsites(); if ($websiteIds = $this->getWebsiteIds()) { - foreach (array_keys($websites) as $websiteId) { - if (!in_array($websiteId, $websiteIds)) { - unset($websites[$websiteId]); - } - } + $websites = array_intersect_key($websites, array_flip($websiteIds)); } return $websites; } -- GitLab From c3fb4a9d697a4564eb2985e371d67f73e2288c05 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Tue, 16 Aug 2016 12:54:12 +0300 Subject: [PATCH 376/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Paypal/Model/Config/StructurePlugin.php | 56 +++-- .../Unit/Model/Config/StructurePluginTest.php | 236 ++++++++---------- 2 files changed, 138 insertions(+), 154 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Config/StructurePlugin.php b/app/code/Magento/Paypal/Model/Config/StructurePlugin.php index 52f46a8411c..3d3f637e542 100644 --- a/app/code/Magento/Paypal/Model/Config/StructurePlugin.php +++ b/app/code/Magento/Paypal/Model/Config/StructurePlugin.php @@ -11,6 +11,9 @@ use Magento\Config\Model\Config\Structure\Element\Section; use Magento\Config\Model\Config\Structure\ElementInterface; use Magento\Paypal\Helper\Backend as BackendHelper; +/** + * Plugin for \Magento\Config\Model\Config\Structure + */ class StructurePlugin { /** @@ -28,6 +31,11 @@ class StructurePlugin */ protected $_scopeDefiner; + /** + * @var bool + */ + private $isSectionChanged; + /** * @var string[] */ @@ -76,36 +84,52 @@ class StructurePlugin * Substitute payment section with PayPal configs * * @param Structure $subject - * @param \Closure $proceed * @param array $pathParts - * @return ElementInterface + * @return array + * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundGetElementByPathParts( - Structure $subject, - \Closure $proceed, - array $pathParts - ) { - $isSectionChanged = $pathParts[0] == 'payment'; - if ($isSectionChanged) { + public function beforeGetElementByPathParts(Structure $subject, array $pathParts) + { + $this->isSectionChanged = $pathParts[0] == 'payment'; + + if ($this->isSectionChanged) { $requestedCountrySection = 'payment_' . strtolower($this->_helper->getConfigurationCountryCode()); + if (in_array($requestedCountrySection, self::getPaypalConfigCountries())) { $pathParts[0] = $requestedCountrySection; } else { $pathParts[0] = 'payment_other'; } } - /** @var ElementInterface $result */ - $result = $proceed($pathParts); - if ($isSectionChanged && isset($result)) { + + return [$pathParts]; + } + + /** + * Substitute payment section with PayPal configs + * + * @param Structure $subject + * @param ElementInterface|null $result + * @return ElementInterface|null + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGetElementByPathParts(Structure $subject, ElementInterface $result = null) + { + if ($this->isSectionChanged && $result) { if ($result instanceof Section) { $this->restructurePayments($result); - $result->setData(array_merge( - $result->getData(), - ['showInDefault' => true, 'showInWebsite' => true, 'showInStore' => true] - ), $this->_scopeDefiner->getScope()); + $result->setData( + array_merge( + $result->getData(), + ['showInDefault' => true, 'showInWebsite' => true, 'showInStore' => true] + ), + $this->_scopeDefiner->getScope() + ); } } + return $result; } diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php index 4479f0a1233..0139566cbf6 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php @@ -3,45 +3,80 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Paypal\Test\Unit\Model\Config; -use Magento\Paypal\Model\Config\StructurePlugin; +use Magento\Paypal\Model\Config\StructurePlugin as ConfigStructurePlugin; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Config\Model\Config\ScopeDefiner as ConfigScopeDefiner; +use Magento\Paypal\Helper\Backend as BackendHelper; +use Magento\Config\Model\Config\Structure as ConfigStructure; +use Magento\Config\Model\Config\Structure\ElementInterface as ElementConfigStructure; class StructurePluginTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\Paypal\Model\Config\StructurePlugin */ - protected $_model; + /** + * @var ConfigStructurePlugin + */ + private $plugin; + + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + /** + * @var ConfigScopeDefiner|\PHPUnit_Framework_MockObject_MockObject + */ + private $configScopeDefinerMock; - /** @var \Magento\Config\Model\Config\ScopeDefiner|\PHPUnit_Framework_MockObject_MockObject */ - protected $_scopeDefiner; + /** + * @var BackendHelper|\PHPUnit_Framework_MockObject_MockObject + */ + private $backendHelperMock; - /** @var \Magento\Paypal\Helper\Backend|\PHPUnit_Framework_MockObject_MockObject */ - protected $_helper; + /** + * @var ConfigStructure|\PHPUnit_Framework_MockObject_MockObject + */ + private $configStructureMock; + + /** + * @var ElementConfigStructure|\PHPUnit_Framework_MockObject_MockObject + */ + private $elementConfigStructureMock; protected function setUp() { - $this->_scopeDefiner = $this->getMock(\Magento\Config\Model\Config\ScopeDefiner::class, [], [], '', false); - $this->_helper = $this->getMock(\Magento\Paypal\Helper\Backend::class, [], [], '', false); - - $objectManagerHelper = new ObjectManagerHelper($this); - $this->_model = $objectManagerHelper->getObject( - \Magento\Paypal\Model\Config\StructurePlugin::class, - ['scopeDefiner' => $this->_scopeDefiner, 'helper' => $this->_helper] + $this->configScopeDefinerMock = $this->getMockBuilder(ConfigScopeDefiner::class) + ->disableOriginalConstructor() + ->getMock(); + $this->backendHelperMock = $this->getMockBuilder(BackendHelper::class) + ->disableOriginalConstructor() + ->getMock(); + $this->configStructureMock = $this->getMockBuilder(ConfigStructure::class) + ->disableOriginalConstructor() + ->getMock(); + $this->elementConfigStructureMock = $this->getMockBuilder(ElementConfigStructure::class) + ->getMockForAbstractClass(); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + ConfigStructurePlugin::class, + ['scopeDefiner' => $this->configScopeDefinerMock, 'helper' => $this->backendHelperMock] ); } public function testGetPaypalConfigCountriesWithOther() { - $countries = StructurePlugin::getPaypalConfigCountries(true); + $countries = ConfigStructurePlugin::getPaypalConfigCountries(true); + $this->assertContains('payment_us', $countries); $this->assertContains('payment_other', $countries); } public function testGetPaypalConfigCountries() { - $countries = StructurePlugin::getPaypalConfigCountries(false); + $countries = ConfigStructurePlugin::getPaypalConfigCountries(false); + $this->assertContains('payment_us', $countries); $this->assertNotContains('payment_other', $countries); } @@ -49,21 +84,27 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase /** * @param array $pathParts * @param bool $returnResult - * @dataProvider aroundGetElementByPathPartsNonPaymentDataProvider + * + * @dataProvider beforeAndAfterGetElementByPathPartsNonPaymentDataProvider */ - public function testAroundGetElementByPathPartsNonPayment($pathParts, $returnResult) + public function testBeforeAndAfterGetElementByPathPartsNonPayment($pathParts, $returnResult) { - $result = $returnResult - ? $this->getMockForAbstractClass(\Magento\Config\Model\Config\Structure\ElementInterface::class) - : null; - $this->_aroundGetElementByPathPartsAssertResult( + $result = $returnResult ? $this->elementConfigStructureMock : null; + + $this->assertEquals( + [$pathParts], + $this->plugin->beforeGetElementByPathParts($this->configStructureMock, $pathParts) + ); + $this->assertSame( $result, - $this->_getElementByPathPartsCallback($pathParts, $result), - $pathParts + $this->plugin->afterGetElementByPathParts($this->configStructureMock, $result) ); } - public function aroundGetElementByPathPartsNonPaymentDataProvider() + /** + * @return array + */ + public function beforeAndAfterGetElementByPathPartsNonPaymentDataProvider() { return [ [['non-payment', 'group1', 'group2', 'field'], true], @@ -77,15 +118,22 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase * @param array $pathParts * @param string $countryCode * @param array $expectedPathParts - * @dataProvider aroundGetElementByPathPartsDataProvider + * + * @dataProvider beforeAndAfterGetElementByPathPartsDataProvider */ - public function testAroundGetElementByPathPartsNoResult($pathParts, $countryCode, $expectedPathParts) + public function testBeforeAndAfterGetElementByPathPartsNoResult($pathParts, $countryCode, $expectedPathParts) { - $this->_getElementByPathPartsPrepareHelper($countryCode); - $this->_aroundGetElementByPathPartsAssertResult( + $this->backendHelperMock->expects(static::once()) + ->method('getConfigurationCountryCode') + ->willReturn($countryCode); + + $this->assertEquals( + [$expectedPathParts], + $this->plugin->beforeGetElementByPathParts($this->configStructureMock, $pathParts) + ); + $this->assertEquals( null, - $this->_getElementByPathPartsCallback($expectedPathParts, null), - $pathParts + $this->plugin->afterGetElementByPathParts($this->configStructureMock, null) ); } @@ -93,20 +141,29 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase * @param array $pathParts * @param string $countryCode * @param array $expectedPathParts - * @dataProvider aroundGetElementByPathPartsDataProvider + * + * @dataProvider beforeAndAfterGetElementByPathPartsDataProvider */ - public function testAroundGetElementByPathParts($pathParts, $countryCode, $expectedPathParts) + public function testBeforeAndAfterGetElementByPathParts($pathParts, $countryCode, $expectedPathParts) { - $this->_getElementByPathPartsPrepareHelper($countryCode); - $result = $this->getMockForAbstractClass(\Magento\Config\Model\Config\Structure\ElementInterface::class); - $this->_aroundGetElementByPathPartsAssertResult( - $result, - $this->_getElementByPathPartsCallback($expectedPathParts, $result), - $pathParts + $this->backendHelperMock->expects(static::once()) + ->method('getConfigurationCountryCode') + ->willReturn($countryCode); + + $this->assertEquals( + [$expectedPathParts], + $this->plugin->beforeGetElementByPathParts($this->configStructureMock, $pathParts) + ); + $this->assertSame( + $this->elementConfigStructureMock, + $this->plugin->afterGetElementByPathParts($this->configStructureMock, $this->elementConfigStructureMock) ); } - public function aroundGetElementByPathPartsDataProvider() + /** + * @return array + */ + public function beforeAndAfterGetElementByPathPartsDataProvider() { return [ [ @@ -121,101 +178,4 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase ], ]; } - - /** - * @param array $pathParts - * @param string $countryCode - * @param array $expectedPathParts - * @dataProvider aroundGetSectionByPathPartsDataProvider - */ - public function testAroundGetSectionByPathParts($pathParts, $countryCode, $expectedPathParts) - { - $this->_getElementByPathPartsPrepareHelper($countryCode); - $result = $this->getMock(\Magento\Config\Model\Config\Structure\Element\Section::class, [], [], '', false); - $self = $this; - $getElementByPathParts = function ($pathParts) use ($self, $expectedPathParts, $result) { - $self->assertEquals($expectedPathParts, $pathParts); - $scope = 'any scope'; - $sectionMap = [ - 'account' => [], - 'recommended_solutions' => [], - 'other_paypal_payment_solutions' => [], - 'other_payment_methods' => [] - ]; - $self->_scopeDefiner->expects($self->any()) - ->method('getScope') - ->will($self->returnValue($scope)); - $result->expects($self->at(0)) - ->method('getData') - ->will($self->returnValue(['children' => []])); - $result->expects($self->at(2)) - ->method('getData') - ->will($self->returnValue(['children' => $sectionMap])); - $result->expects($self->at(1)) - ->method('setData') - ->with(['children' => $sectionMap], $scope) - ->will($self->returnSelf()); - $result->expects($self->at(3)) - ->method('setData') - ->with(['children' => $sectionMap, - 'showInDefault' => true, - 'showInWebsite' => true, - 'showInStore' => true], $scope) - ->will($self->returnSelf()); - return $result; - }; - $this->_aroundGetElementByPathPartsAssertResult($result, $getElementByPathParts, $pathParts); - } - - public function aroundGetSectionByPathPartsDataProvider() - { - return [ - [['payment'], 'GB', ['payment_gb']], - [['payment'], 'any', ['payment_other']], - ]; - } - - /** - * Assert result of aroundGetElementByPathParts method - * - * @param \PHPUnit_Framework_MockObject_MockObject|null $result - * @param \Closure $getElementByPathParts - * @param array $pathParts - */ - private function _aroundGetElementByPathPartsAssertResult($result, $getElementByPathParts, $pathParts) - { - $this->assertEquals($result, $this->_model->aroundGetElementByPathParts( - $this->getMock(\Magento\Config\Model\Config\Structure::class, [], [], '', false), - $getElementByPathParts, - $pathParts - )); - } - - /** - * Get callback for aroundGetElementByPathParts method - * - * @param array $expectedPathParts - * @param \PHPUnit_Framework_MockObject_MockObject|null $result - * @return \Closure - */ - private function _getElementByPathPartsCallback($expectedPathParts, $result) - { - $self = $this; - return function ($pathParts) use ($self, $expectedPathParts, $result) { - $self->assertEquals($expectedPathParts, $pathParts); - return $result; - }; - } - - /** - * Prepare helper for test - * - * @param string $countryCode - */ - private function _getElementByPathPartsPrepareHelper($countryCode) - { - $this->_helper->expects($this->once()) - ->method('getConfigurationCountryCode') - ->will($this->returnValue($countryCode)); - } } -- GitLab From ce5171f965ec03b4961be84e2d9f553de9a52f02 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Tue, 16 Aug 2016 13:37:47 +0300 Subject: [PATCH 377/838] MAGETWO-55193: Extension Management with Marketplace data - Update css --- setup/pub/styles/setup.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pub/styles/setup.css b/setup/pub/styles/setup.css index 72ad9b834a8..61893c04c3f 100644 --- a/setup/pub/styles/setup.css +++ b/setup/pub/styles/setup.css @@ -3,4 +3,4 @@ * See COPYING.txt for license details. */ -.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.8rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{padding-top:.8rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.component-indicator._tooltip{background:0 0;margin:0 0 8px 5px}.component-indicator._tooltip a{width:21px}.component-indicator._tooltip a:hover{text-decoration:none}.component-indicator._tooltip a:before{color:#514943;content:'\e633';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file +.abs-action-delete,.abs-icon,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.validation-symbol:after{color:#e22626;content:'*';font-weight:400;margin-left:3px}.abs-modal-overlay,.modals-overlay{background:rgba(0,0,0,.35);bottom:0;left:0;position:fixed;right:0;top:0}.abs-action-delete>span,.abs-visually-hidden,.action-multicheck-wrap .action-multicheck-toggle>span,.admin__actions-switch-checkbox,.admin__control-fields .admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label)>.admin__field-label,.admin__field-tooltip .admin__field-tooltip-action span,.customize-your-store .customize-your-store-default .legend,.extensions-information .list .extension-delete>span,.form-el-checkbox,.form-el-radio,.selectmenu .action-delete>span,.selectmenu .action-edit>span,.selectmenu .action-save>span,.selectmenu-toggle span,.tooltip .help a span,.tooltip .help span span,[class*=admin__control-grouped]>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.abs-visually-hidden-reset,.admin__field-group-columns>.admin__field:nth-child(n+2):not(.admin__field-option):not(.admin__field-group-show-label):not(.admin__field-date)>.admin__field-label[class]{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.abs-clearfix:after,.abs-clearfix:before,.action-multicheck-wrap:after,.action-multicheck-wrap:before,.actions-split:after,.actions-split:before,.admin__control-table-pagination:after,.admin__control-table-pagination:before,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:before,.admin__data-grid-filters-footer:after,.admin__data-grid-filters-footer:before,.admin__data-grid-filters:after,.admin__data-grid-filters:before,.admin__data-grid-header-row:after,.admin__data-grid-header-row:before,.admin__field-complex:after,.admin__field-complex:before,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .magento-message .insert-title-inner:before,.modal-slide .main-col .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:before,.page-actions._fixed:after,.page-actions._fixed:before,.page-content:after,.page-content:before,.page-header-actions:after,.page-header-actions:before,.page-main-actions:not(._hidden):after,.page-main-actions:not(._hidden):before{content:'';display:table}.abs-clearfix:after,.action-multicheck-wrap:after,.actions-split:after,.admin__control-table-pagination:after,.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content:after,.admin__data-grid-filters-footer:after,.admin__data-grid-filters:after,.admin__data-grid-header-row:after,.admin__field-complex:after,.modal-slide .magento-message .insert-title-inner:after,.modal-slide .main-col .insert-title-inner:after,.page-actions._fixed:after,.page-content:after,.page-header-actions:after,.page-main-actions:not(._hidden):after{clear:both}.abs-list-reset-styles{margin:0;padding:0;list-style:none}.abs-draggable-handle,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle,.admin__control-table .draggable-handle,.data-grid .data-grid-draggable-row-cell .draggable-handle{cursor:-webkit-grab;cursor:move;font-size:0;margin-top:-4px;padding:0 1rem 0 0;vertical-align:middle;display:inline-block;text-decoration:none}.abs-draggable-handle:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:before,.admin__control-table .draggable-handle:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:before{-webkit-font-smoothing:antialiased;font-size:1.8rem;line-height:inherit;color:#9e9e9e;content:'\e617';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.abs-draggable-handle:hover:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .draggable-handle:hover:before,.admin__control-table .draggable-handle:hover:before,.data-grid .data-grid-draggable-row-cell .draggable-handle:hover:before{color:#858585}.abs-config-scope-label,.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]:before{bottom:-1.3rem;color:gray;content:attr(data-config-scope);font-size:1.1rem;font-weight:400;min-width:15rem;position:absolute;right:0;text-transform:lowercase}.abs-word-wrap,.admin__field:not(.admin__field-option)>.admin__field-label{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;box-sizing:border-box}*,:after,:before{box-sizing:inherit}:focus{box-shadow:none;outline:0}._keyfocus :focus{box-shadow:0 0 0 1px #008bdb}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}mark{background:#ff0;color:#000}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}embed,img,object,video{max-width:100%}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/light/opensans-300.eot);src:url(../fonts/opensans/light/opensans-300.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/light/opensans-300.woff2) format('woff2'),url(../fonts/opensans/light/opensans-300.woff) format('woff'),url(../fonts/opensans/light/opensans-300.ttf) format('truetype'),url('../fonts/opensans/light/opensans-300.svg#Open Sans') format('svg');font-weight:300;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/regular/opensans-400.eot);src:url(../fonts/opensans/regular/opensans-400.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/regular/opensans-400.woff2) format('woff2'),url(../fonts/opensans/regular/opensans-400.woff) format('woff'),url(../fonts/opensans/regular/opensans-400.ttf) format('truetype'),url('../fonts/opensans/regular/opensans-400.svg#Open Sans') format('svg');font-weight:400;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/semibold/opensans-600.eot);src:url(../fonts/opensans/semibold/opensans-600.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/semibold/opensans-600.woff2) format('woff2'),url(../fonts/opensans/semibold/opensans-600.woff) format('woff'),url(../fonts/opensans/semibold/opensans-600.ttf) format('truetype'),url('../fonts/opensans/semibold/opensans-600.svg#Open Sans') format('svg');font-weight:600;font-style:normal}@font-face{font-family:'Open Sans';src:url(../fonts/opensans/bold/opensans-700.eot);src:url(../fonts/opensans/bold/opensans-700.eot?#iefix) format('embedded-opentype'),url(../fonts/opensans/bold/opensans-700.woff2) format('woff2'),url(../fonts/opensans/bold/opensans-700.woff) format('woff'),url(../fonts/opensans/bold/opensans-700.ttf) format('truetype'),url('../fonts/opensans/bold/opensans-700.svg#Open Sans') format('svg');font-weight:700;font-style:normal}html{font-size:62.5%}body{color:#333;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.36;font-size:1.4rem}h1{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2.8rem}h2{margin:0 0 2rem;color:#41362f;font-weight:400;line-height:1.2;font-size:2rem}h3{margin:0 0 2rem;color:#41362f;font-weight:600;line-height:1.2;font-size:1.7rem}h4,h5,h6{font-weight:600;margin-top:0}p{margin:0 0 1em}small{font-size:1.2rem}a{color:#008bdb;text-decoration:none}a:hover{color:#0fa7ff;text-decoration:underline}dl,ol,ul{padding-left:0}nav ol,nav ul{list-style:none;margin:0;padding:0}html{height:100%}body{background-color:#fff;min-height:100%;min-width:102.4rem}.page-wrapper{background-color:#fff;display:inline-block;margin-left:-4px;vertical-align:top;width:calc(100% - 8.8rem)}.page-content{padding-bottom:3rem;padding-left:3rem;padding-right:3rem}.notices-wrapper{margin:0 3rem}.notices-wrapper .messages{margin-bottom:0}.row{margin-left:0;margin-right:0}.row:after{clear:both;content:'';display:table}.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9,.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{min-height:1px;padding-left:0;padding-right:0;position:relative}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}.row-gutter{margin-left:-1.5rem;margin-right:-1.5rem}.row-gutter>[class*=col-]{padding-left:1.5rem;padding-right:1.5rem}.abs-clearer:after,.extension-manager-content:after,.extension-manager-title:after,.form-row:after,.header:after,.nav:after,body:after{clear:both;content:'';display:table}.ng-cloak{display:none!important}.hide.hide{display:none}.show.show{display:block}.text-center{text-align:center}.text-right{text-align:right}@font-face{font-family:Icons;src:url(../fonts/icons/icons.eot);src:url(../fonts/icons/icons.eot?#iefix) format('embedded-opentype'),url(../fonts/icons/icons.woff2) format('woff2'),url(../fonts/icons/icons.woff) format('woff'),url(../fonts/icons/icons.ttf) format('truetype'),url(../fonts/icons/icons.svg#Icons) format('svg');font-weight:400;font-style:normal}[class*=icon-]{display:inline-block;line-height:1}.icon-failed:before,.icon-success:before,[class*=icon-]:after{font-family:Icons}.icon-success{color:#79a22e}.icon-success:before{content:'\e62d'}.icon-failed{color:#e22626}.icon-failed:before{content:'\e632'}.icon-success-thick:after{content:'\e62d'}.icon-collapse:after{content:'\e615'}.icon-failed-thick:after{content:'\e632'}.icon-expand:after{content:'\e616'}.icon-warning:after{content:'\e623'}.icon-failed-round,.icon-success-round{border-radius:100%;color:#fff;font-size:2.5rem;height:1em;position:relative;text-align:center;width:1em}.icon-failed-round:after,.icon-success-round:after{bottom:0;font-size:.5em;left:0;position:absolute;right:0;top:.45em}.icon-success-round{background-color:#79a22e}.icon-success-round:after{content:'\e62d'}.icon-failed-round{background-color:#e22626}.icon-failed-round:after{content:'\e632'}dl,ol,ul{margin-top:0}.list{padding-left:0}.list>li{display:block;margin-bottom:.75em;position:relative}.list>li>.icon-failed,.list>li>.icon-success{font-size:1.6em;left:-.1em;position:absolute;top:0}.list>li>.icon-success{color:#79a22e}.list>li>.icon-failed{color:#e22626}.list-item-failed,.list-item-icon,.list-item-success,.list-item-warning{padding-left:3.5rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{left:-.1em;position:absolute}.list-item-success:before{color:#79a22e}.list-item-failed:before{color:#e22626}.list-item-warning:before{color:#ef672f}.list-definition{margin:0 0 3rem;padding:0}.list-definition>dt{clear:left;float:left}.list-definition>dd{margin-bottom:1em;margin-left:20rem}.btn-wrap{margin:0 auto}.btn-wrap .btn{width:100%}.btn{background:#e3e3e3;border:none;color:#514943;display:inline-block;font-size:1.6rem;font-weight:600;padding:.45em .9em;text-align:center}.btn:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.btn:active{background-color:#d6d6d6}.btn.disabled,.btn[disabled]{cursor:default;opacity:.5;pointer-events:none}.ie9 .btn.disabled,.ie9 .btn[disabled]{background-color:#f0f0f0;opacity:1;text-shadow:none}.btn-large{padding:.75em 1.25em}.btn-medium{font-size:1.4rem;padding:.5em 1.5em .6em}.btn-link{background-color:transparent;border:none;color:#008bdb;font-family:1.6rem;font-size:1.5rem}.btn-link:active,.btn-link:focus,.btn-link:hover{background-color:transparent;color:#0fa7ff}.btn-prime{background-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.btn-prime:focus,.btn-prime:hover{background-color:#f65405;background-repeat:repeat-x;background-image:linear-gradient(to right,#e04f00 0,#f65405 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e04f00', endColorstr='#f65405', GradientType=1);color:#fff}.btn-prime:active{background-color:#e04f00;background-repeat:repeat-x;background-image:linear-gradient(to right,#f65405 0,#e04f00 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f65405', endColorstr='#e04f00', GradientType=1);color:#fff}.ie9 .btn-prime.disabled,.ie9 .btn-prime[disabled]{background-color:#fd6e23}.ie9 .btn-prime.disabled:active,.ie9 .btn-prime.disabled:hover,.ie9 .btn-prime[disabled]:active,.ie9 .btn-prime[disabled]:hover{background-color:#fd6e23;-webkit-filter:none;filter:none}.btn-secondary{background-color:#514943;color:#fff}.btn-secondary:hover{background-color:#5f564f;color:#fff}.btn-secondary:active,.btn-secondary:focus{background-color:#574e48;color:#fff}.ie9 .btn-secondary.disabled,.ie9 .btn-secondary[disabled]{background-color:#514943}.ie9 .btn-secondary.disabled:active,.ie9 .btn-secondary[disabled]:active{background-color:#514943;-webkit-filter:none;filter:none}[class*=btn-wrap-triangle]{overflow:hidden;position:relative}[class*=btn-wrap-triangle] .btn:after{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.btn-wrap-triangle-right{display:inline-block;padding-right:1.74rem;position:relative}.btn-wrap-triangle-right .btn{text-indent:.92rem}.btn-wrap-triangle-right .btn:after{border-color:transparent transparent transparent #e3e3e3;border-width:1.84rem 0 1.84rem 1.84rem;left:100%;margin-left:-1.74rem}.btn-wrap-triangle-right .btn:focus:after,.btn-wrap-triangle-right .btn:hover:after{border-left-color:#dbdbdb}.btn-wrap-triangle-right .btn:active:after{border-left-color:#d6d6d6}.btn-wrap-triangle-right .btn:not(.disabled):active,.btn-wrap-triangle-right .btn:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn.disabled:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:after{border-color:transparent transparent transparent #f0f0f0}.ie9 .btn-wrap-triangle-right .btn.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn.disabled:focus:after,.ie9 .btn-wrap-triangle-right .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:focus:after,.ie9 .btn-wrap-triangle-right .btn[disabled]:hover:after{border-left-color:#f0f0f0}.btn-wrap-triangle-right .btn-prime:after{border-color:transparent transparent transparent #eb5202}.btn-wrap-triangle-right .btn-prime:focus:after,.btn-wrap-triangle-right .btn-prime:hover:after{border-left-color:#f65405}.btn-wrap-triangle-right .btn-prime:active:after{border-left-color:#e04f00}.btn-wrap-triangle-right .btn-prime:not(.disabled):active,.btn-wrap-triangle-right .btn-prime:not([disabled]):active{left:1px}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:after{border-color:transparent transparent transparent #fd6e23}.ie9 .btn-wrap-triangle-right .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-right .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-right .btn-prime[disabled]:hover:after{border-left-color:#fd6e23}.btn-wrap-triangle-left{display:inline-block;padding-left:1.74rem}.btn-wrap-triangle-left .btn{text-indent:-.92rem}.btn-wrap-triangle-left .btn:after{border-color:transparent #e3e3e3 transparent transparent;border-width:1.84rem 1.84rem 1.84rem 0;margin-right:-1.74rem;right:100%}.btn-wrap-triangle-left .btn:focus:after,.btn-wrap-triangle-left .btn:hover:after{border-right-color:#dbdbdb}.btn-wrap-triangle-left .btn:active:after{border-right-color:#d6d6d6}.btn-wrap-triangle-left .btn:not(.disabled):active,.btn-wrap-triangle-left .btn:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn.disabled:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:after{border-color:transparent #f0f0f0 transparent transparent}.ie9 .btn-wrap-triangle-left .btn.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn[disabled]:hover:after{border-right-color:#f0f0f0}.btn-wrap-triangle-left .btn-prime:after{border-color:transparent #eb5202 transparent transparent}.btn-wrap-triangle-left .btn-prime:focus:after,.btn-wrap-triangle-left .btn-prime:hover:after{border-right-color:#e04f00}.btn-wrap-triangle-left .btn-prime:active:after{border-right-color:#f65405}.btn-wrap-triangle-left .btn-prime:not(.disabled):active,.btn-wrap-triangle-left .btn-prime:not([disabled]):active{right:1px}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:after{border-color:transparent #fd6e23 transparent transparent}.ie9 .btn-wrap-triangle-left .btn-prime.disabled:active:after,.ie9 .btn-wrap-triangle-left .btn-prime.disabled:hover:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:active:after,.ie9 .btn-wrap-triangle-left .btn-prime[disabled]:hover:after{border-right-color:#fd6e23}.btn-expand{background-color:transparent;border:none;color:#303030;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700;padding:0;position:relative}.btn-expand.expanded:after{border-color:transparent transparent #303030;border-width:0 .285em .36em}.btn-expand.expanded:hover:after{border-color:transparent transparent #3d3d3d}.btn-expand:hover{background-color:transparent;border:none;color:#3d3d3d}.btn-expand:hover:after{border-color:#3d3d3d transparent transparent}.btn-expand:after{border-color:#303030 transparent transparent;border-style:solid;border-width:.36em .285em 0;content:'';height:0;left:100%;margin-left:.5em;margin-top:-.18em;position:absolute;top:50%;width:0}[class*=col-] .form-el-input,[class*=col-] .form-el-select{width:100%}.form-fieldset{border:none;margin:0 0 1em;padding:0}.form-row{margin-bottom:2.2rem}.form-row .form-row{margin-bottom:.4rem}.form-row .form-label{display:block;font-weight:600;padding:.6rem 2.1em 0 0;text-align:right}.form-row .form-label.required{position:relative}.form-row .form-label.required:after{color:#eb5202;content:'*';font-size:1.15em;position:absolute;right:.7em;top:.5em}.form-row .form-el-checkbox+.form-label:before,.form-row .form-el-radio+.form-label:before{top:.7rem}.form-row .form-el-checkbox+.form-label:after,.form-row .form-el-radio+.form-label:after{top:1.1rem}.form-row.form-row-text{padding-top:.6rem}.form-row.form-row-text .action-sign-out{font-size:1.2rem;margin-left:1rem}.form-note{font-size:1.2rem;font-weight:600;margin-top:1rem}.form-el-dummy{display:none}.fieldset{border:0;margin:0;min-width:0;padding:0}input:not([disabled]):focus,textarea:not([disabled]):focus{box-shadow:none}.form-el-input{border:1px solid #adadad;color:#303030;padding:.35em .55em .5em}.form-el-input:hover{border-color:#949494}.form-el-input:focus{border-color:#008bdb}.form-el-input:required{box-shadow:none}.form-label{margin-bottom:.5em}[class*=form-label][for]{cursor:pointer}.form-el-insider-wrap{display:table;width:100%}.form-el-insider-input{display:table-cell;width:100%}.form-el-insider{border-radius:2px;display:table-cell;padding:.43em .55em .5em 0;vertical-align:top}.form-legend,.form-legend-expand,.form-legend-light{display:block;margin:0}.form-legend,.form-legend-expand{font-size:1.25em;font-weight:600;margin-bottom:2.5em;padding-top:1.5em}.form-legend{border-top:1px solid #ccc;width:100%}.form-legend-light{font-size:1em;margin-bottom:1.5em}.form-legend-expand{cursor:pointer;transition:opacity .2s linear}.form-legend-expand:hover{opacity:.85}.form-legend-expand.expanded:after{content:'\e615'}.form-legend-expand:after{content:'\e616';font-family:Icons;font-size:1.15em;font-weight:400;margin-left:.5em;vertical-align:sub}.form-el-checkbox.disabled+.form-label,.form-el-checkbox.disabled+.form-label:before,.form-el-checkbox[disabled]+.form-label,.form-el-checkbox[disabled]+.form-label:before,.form-el-radio.disabled+.form-label,.form-el-radio.disabled+.form-label:before,.form-el-radio[disabled]+.form-label,.form-el-radio[disabled]+.form-label:before{cursor:default;opacity:.5;pointer-events:none}.form-el-checkbox:not(.disabled)+.form-label:hover:before,.form-el-checkbox:not([disabled])+.form-label:hover:before,.form-el-radio:not(.disabled)+.form-label:hover:before,.form-el-radio:not([disabled])+.form-label:hover:before{border-color:#514943}.form-el-checkbox+.form-label,.form-el-radio+.form-label{font-weight:400;padding-left:2em;padding-right:0;position:relative;text-align:left;transition:border-color .1s linear}.form-el-checkbox+.form-label:before,.form-el-radio+.form-label:before{border:1px solid;content:'';left:0;position:absolute;top:.1rem;transition:border-color .1s linear}.form-el-checkbox+.form-label:before{background-color:#fff;border-color:#adadad;border-radius:2px;font-size:1.2rem;height:1.6rem;line-height:1.2;width:1.6rem}.form-el-checkbox:checked+.form-label::before{content:'\e62d';font-family:Icons}.form-el-radio+.form-label:before{background-color:#fff;border:1px solid #adadad;border-radius:100%;height:1.8rem;width:1.8rem}.form-el-radio+.form-label:after{background:0 0;border:.5rem solid transparent;border-radius:100%;content:'';height:0;left:.4rem;position:absolute;top:.5rem;transition:background .3s linear;width:0}.form-el-radio:checked+.form-label{cursor:default}.form-el-radio:checked+.form-label:after{border-color:#514943}.form-select-label{border:1px solid #adadad;color:#303030;cursor:pointer;display:block;overflow:hidden;position:relative;z-index:0}.form-select-label:hover,.form-select-label:hover:after{border-color:#949494}.form-select-label:active,.form-select-label:active:after,.form-select-label:focus,.form-select-label:focus:after{border-color:#008bdb}.form-select-label:after{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:2.36em;z-index:-2}.ie9 .form-select-label:after{display:none}.form-select-label:before{border-color:#303030 transparent transparent;border-style:solid;border-width:5px 4px 0;content:'';height:0;margin-right:-4px;margin-top:-2.5px;position:absolute;right:1.18em;top:50%;width:0;z-index:-1}.ie9 .form-select-label:before{display:none}.form-select-label .form-el-select{background:0 0;border:none;border-radius:0;content:'';display:block;margin:0;padding:.35em calc(2.36em + 10%) .5em .55em;width:110%}.ie9 .form-select-label .form-el-select{padding-right:.55em;width:100%}.form-select-label .form-el-select::-ms-expand{display:none}.form-el-select{background:#fff;border:1px solid #adadad;border-radius:2px;color:#303030;display:block;padding:.35em .55em}.multiselect-custom{border:1px solid #adadad;height:45.2rem;margin:0 0 1.5rem;overflow:auto;position:relative}.multiselect-custom ul{margin:0;padding:0;list-style:none;min-width:29rem}.multiselect-custom .item{padding:1rem 1.4rem}.multiselect-custom .selected{background-color:#e0f6fe}.multiselect-custom .form-label{margin-bottom:0}[class*=form-el-].invalid{border-color:#e22626}[class*=form-el-].invalid+.error-container{display:block}.error-container{background-color:#fffbbb;border:1px solid #ee7d7d;color:#514943;display:none;font-size:1.19rem;margin-top:.2rem;padding:.8rem 1rem .9rem}.check-result-message{margin-left:.5em;min-height:3.68rem;-ms-align-items:center;-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex}.check-result-text{margin-left:.5em}body:not([class]){min-width:0}.container{display:block;margin:0 auto 4rem;max-width:100rem;padding:0}.abs-action-delete,.action-close:before,.action-next:before,.action-previous:before,.admin-user .admin__action-dropdown:before,.admin__action-multiselect-dropdown:before,.admin__action-multiselect-search-label:before,.admin__control-checkbox+label:before,.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before,.admin__control-table .action-delete:before,.admin__current-filters-list .action-remove:before,.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before,.admin__data-grid-action-bookmarks .admin__action-dropdown:before,.admin__data-grid-action-columns .admin__action-dropdown:before,.admin__data-grid-action-export .admin__action-dropdown:before,.admin__field-fallback-reset:before,.admin__menu .level-0>a:before,.admin__page-nav-item-message .admin__page-nav-item-message-icon,.admin__page-nav-title._collapsible:after,.data-grid-filters-action-wrap .action-default:before,.data-grid-row-changed:after,.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before,.data-grid-search-control-wrap .action-submit:before,.extensions-information .list .extension-delete,.icon-failed:before,.icon-success:before,.notifications-action:before,.notifications-close:before,.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before,.page-title-jumbo-success:before,.search-global-label:before,.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before,.setup-home-item:before,.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before,.store-switcher .dropdown-menu .dropdown-toolbar a:before,.tooltip .help a:before,.tooltip .help span:before{-webkit-font-smoothing:antialiased;font-family:Icons;font-style:normal;font-weight:400;line-height:1;speak:none}.text-stretch{margin-bottom:1.5em}.page-title-jumbo{font-size:4rem;font-weight:300;letter-spacing:-.05em;margin-bottom:2.9rem}.page-title-jumbo-success:before{color:#79a22e;content:'\e62d';font-size:3.9rem;margin-left:-.3rem;margin-right:2.4rem}.list{margin-bottom:3rem}.list-dot .list-item{display:list-item;list-style-position:inside;margin-bottom:1.2rem}.list-title{color:#333;font-size:1.4rem;font-weight:700;letter-spacing:.025em;margin-bottom:1.2rem}.list-item-failed:before,.list-item-success:before,.list-item-warning:before{font-family:Icons;font-size:1.6rem;top:0}.list-item-success:before{content:'\e62d';font-size:1.6rem}.list-item-failed:before{content:'\e632';font-size:1.4rem;left:.1rem;top:.2rem}.list-item-warning:before{content:'\e623';font-size:1.3rem;left:.2rem}.form-wrap{margin-bottom:3.6rem;padding-top:2.1rem}.form-el-label-horizontal{display:inline-block;font-size:1.3rem;font-weight:600;letter-spacing:.025em;margin-bottom:.4rem;margin-left:.4rem}.app-updater{min-width:768px}body._has-modal{height:100%;overflow:hidden;width:100%}.modals-overlay{z-index:899}.modal-popup,.modal-slide{bottom:0;min-width:0;position:fixed;right:0;top:0;visibility:hidden}.modal-popup._show,.modal-slide._show{visibility:visible}.modal-popup._show .modal-inner-wrap,.modal-slide._show .modal-inner-wrap{-ms-transform:translate(0,0);transform:translate(0,0)}.modal-popup .modal-inner-wrap,.modal-slide .modal-inner-wrap{background-color:#fff;box-shadow:0 0 12px 2px rgba(0,0,0,.35);opacity:1;pointer-events:auto}.modal-slide{left:14.8rem;z-index:900}.modal-slide._show .modal-inner-wrap{-ms-transform:translateX(0);transform:translateX(0)}.modal-slide .modal-inner-wrap{height:100%;overflow-y:auto;position:static;-ms-transform:translateX(100%);transform:translateX(100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;width:auto}.modal-slide._inner-scroll .modal-inner-wrap{overflow-y:visible;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.modal-slide._inner-scroll .modal-footer,.modal-slide._inner-scroll .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-slide._inner-scroll .modal-content{overflow-y:auto}.modal-slide._inner-scroll .modal-footer{margin-top:auto}.modal-slide .modal-content,.modal-slide .modal-footer,.modal-slide .modal-header{padding:0 2.6rem 2.6rem}.modal-slide .modal-header{padding-bottom:2.1rem;padding-top:2.1rem}.modal-popup{z-index:900;left:0;overflow-y:auto}.modal-popup._show .modal-inner-wrap{-ms-transform:translateY(0);transform:translateY(0)}.modal-popup .modal-inner-wrap{margin:5rem auto;width:75%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box;height:auto;left:0;position:absolute;right:0;-ms-transform:translateY(-200%);transform:translateY(-200%);transition-duration:.2s;transition-property:transform,visibility;transition-timing-function:ease}.modal-popup._inner-scroll{overflow-y:visible}.ie10 .modal-popup._inner-scroll,.ie9 .modal-popup._inner-scroll{overflow-y:auto}.modal-popup._inner-scroll .modal-inner-wrap{max-height:90%}.ie10 .modal-popup._inner-scroll .modal-inner-wrap,.ie9 .modal-popup._inner-scroll .modal-inner-wrap{max-height:none}.modal-popup._inner-scroll .modal-content{overflow-y:auto}.modal-popup .modal-content,.modal-popup .modal-footer,.modal-popup .modal-header{padding-left:3rem;padding-right:3rem}.modal-popup .modal-footer,.modal-popup .modal-header{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0}.modal-popup .modal-header{padding-bottom:1.2rem;padding-top:3rem}.modal-popup .modal-footer{margin-top:auto;padding-bottom:3rem}.modal-popup .modal-footer-actions{text-align:right}.admin__action-dropdown-wrap{display:inline-block;position:relative}.admin__action-dropdown-wrap .admin__action-dropdown-text:after{left:-6px;right:0}.admin__action-dropdown-wrap .admin__action-dropdown-menu{left:auto;right:0}.admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__action-dropdown-wrap.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin__action-dropdown-wrap._active .admin__action-dropdown-text:after,.admin__action-dropdown-wrap.active .admin__action-dropdown-text:after{background-color:#fff;content:'';height:6px;position:absolute;top:100%}.admin__action-dropdown-wrap._active .admin__action-dropdown-menu,.admin__action-dropdown-wrap.active .admin__action-dropdown-menu{display:block}.admin__action-dropdown-wrap._disabled .admin__action-dropdown{cursor:default}.admin__action-dropdown-wrap._disabled:hover .admin__action-dropdown{color:#333}.admin__action-dropdown{background-color:#fff;border:1px solid transparent;border-bottom:none;border-radius:0;box-shadow:none;color:#333;display:inline-block;font-size:1.3rem;font-weight:400;letter-spacing:-.025em;padding:.7rem 3.3rem .8rem 1.5rem;position:relative;vertical-align:baseline;z-index:2}.admin__action-dropdown._active:after,.admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .admin__action-dropdown:after,.active .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin__action-dropdown:focus,.admin__action-dropdown:hover{background-color:#fff;color:#000;text-decoration:none}.admin__action-dropdown:after{right:1.5rem}.admin__action-dropdown:before{margin-right:1rem}.admin__action-dropdown-menu{background-color:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;line-height:1.36;margin-top:-1px;min-width:120%;padding:.5rem 1rem;position:absolute;top:100%;transition:all .15s ease;z-index:1}.admin__action-dropdown-menu>li{display:block}.admin__action-dropdown-menu>li>a{color:#333;display:block;text-decoration:none;padding:.6rem .5rem}.selectmenu{display:inline-block;position:relative;text-align:left;z-index:1}.selectmenu._active{border-color:#007bdb;z-index:500}.selectmenu .action-delete,.selectmenu .action-edit,.selectmenu .action-save{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 1rem}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover,.selectmenu .action-save:hover{background-color:transparent;border-color:transparent;box-shadow:none}.selectmenu .action-delete:before,.selectmenu .action-edit:before,.selectmenu .action-save:before{content:'\e630'}.selectmenu .action-delete,.selectmenu .action-edit{border:0 solid #fff;border-left-width:1px;bottom:0;position:absolute;right:0;top:0;z-index:1}.selectmenu .action-delete:hover,.selectmenu .action-edit:hover{border:0 solid #fff;border-left-width:1px}.selectmenu .action-save:before{content:'\e625'}.selectmenu .action-edit:before{content:'\e631'}.selectmenu-value{display:inline-block}.selectmenu-value input[type=text]{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;border:0;display:inline;margin:0;width:6rem}body._keyfocus .selectmenu-value input[type=text]:focus{box-shadow:none}.selectmenu-toggle{padding-right:3rem;background:0 0;border-width:0;bottom:0;float:right;position:absolute;right:0;top:0;width:0}.selectmenu-toggle._active:after,.selectmenu-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.1rem;top:50%;transition:all .2s linear;width:0}._active .selectmenu-toggle:after,.active .selectmenu-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.selectmenu-toggle:hover:after{border-color:#000 transparent transparent}.selectmenu-toggle:active,.selectmenu-toggle:focus,.selectmenu-toggle:hover{background:0 0}.selectmenu._active .selectmenu-toggle:before{border-color:#007bdb}body._keyfocus .selectmenu-toggle:focus{box-shadow:none}.selectmenu-toggle:before{background:#e3e3e3;border-left:1px solid #adadad;bottom:0;content:'';display:block;position:absolute;right:0;top:0;width:3.2rem}.selectmenu-items{background:#fff;border:1px solid #007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);display:none;float:left;left:-1px;margin-top:3px;max-width:20rem;min-width:calc(100% + 2px);position:absolute;top:100%}.selectmenu-items._active{display:block}.selectmenu-items ul{float:left;list-style-type:none;margin:0;min-width:100%;padding:0}.selectmenu-items li{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row;transition:background .2s linear}.selectmenu-items li:hover{background:#e3e3e3}.selectmenu-items li:last-child .selectmenu-item-action,.selectmenu-items li:last-child .selectmenu-item-action:visited{color:#008bdb;text-decoration:none}.selectmenu-items li:last-child .selectmenu-item-action:hover{color:#0fa7ff;text-decoration:underline}.selectmenu-items li:last-child .selectmenu-item-action:active{color:#ff5501;text-decoration:underline}.selectmenu-item{position:relative;width:100%;z-index:1}li._edit>.selectmenu-item{display:none}.selectmenu-item-edit{display:none;padding:.3rem 4rem .3rem .4rem;position:relative;white-space:nowrap;z-index:1}li:last-child .selectmenu-item-edit{padding-right:.4rem}.selectmenu-item-edit .admin__control-text{margin:0;width:5.4rem}li._edit .selectmenu-item-edit{display:block}.selectmenu-item-action{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background:0 0;border:0;color:#333;display:block;font-size:1.4rem;font-weight:400;min-width:100%;padding:1rem 6rem 1rem 1.5rem;text-align:left;transition:background .2s linear;width:5rem}.selectmenu-item-action:focus,.selectmenu-item-action:hover{background:#e3e3e3}.abs-actions-split-xl .action-default,.page-actions .actions-split .action-default{margin-right:4rem}.abs-actions-split-xl .action-toggle,.page-actions .actions-split .action-toggle{padding-right:4rem}.abs-actions-split-xl .action-toggle:after,.page-actions .actions-split .action-toggle:after{border-width:.9rem .6rem 0;margin-top:-.3rem;right:1.4rem}.actions-split{position:relative;z-index:400}.actions-split._active,.actions-split.active,.actions-split:hover{box-shadow:0 0 0 1px #007bdb}.actions-split._active .action-toggle.action-primary,.actions-split._active .action-toggle.primary,.actions-split.active .action-toggle.action-primary,.actions-split.active .action-toggle.primary{background-color:#ba4000;border-color:#ba4000}.actions-split._active .dropdown-menu,.actions-split.active .dropdown-menu{opacity:1;visibility:visible;display:block}.actions-split .action-default,.actions-split .action-toggle{float:left;margin:0}.actions-split .action-default._active,.actions-split .action-default.active,.actions-split .action-default:hover,.actions-split .action-toggle._active,.actions-split .action-toggle.active,.actions-split .action-toggle:hover{box-shadow:none}.actions-split .action-default{margin-right:3.2rem;min-width:9.3rem}.actions-split .action-toggle{padding-right:3.2rem;border-left-color:rgba(0,0,0,.2);bottom:0;padding-left:0;position:absolute;right:0;top:0}.actions-split .action-toggle._active:after,.actions-split .action-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .actions-split .action-toggle:after,.active .actions-split .action-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.actions-split .action-toggle:hover:after{border-color:#000 transparent transparent}.actions-split .action-toggle.action-primary:after,.actions-split .action-toggle.action-secondary:after,.actions-split .action-toggle.primary:after,.actions-split .action-toggle.secondary:after{border-color:#fff transparent transparent}.actions-split .action-toggle>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-select-wrap{display:inline-block;position:relative}.action-select-wrap .action-select{padding-right:3.2rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#fff;font-weight:400;text-align:left}.action-select-wrap .action-select._active:after,.action-select-wrap .action-select.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.2rem;top:50%;transition:all .2s linear;width:0}._active .action-select-wrap .action-select:after,.active .action-select-wrap .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .action-select:hover:after{border-color:#000 transparent transparent}.action-select-wrap .action-select:hover,.action-select-wrap .action-select:hover:before{border-color:#878787}.action-select-wrap .action-select:before{background-color:#e3e3e3;border:1px solid #adadad;bottom:0;content:'';position:absolute;right:0;top:0;width:3.2rem}.action-select-wrap .action-select._active{border-color:#007bdb}.action-select-wrap .action-select._active:before{border-color:#007bdb #007bdb #007bdb #adadad}.action-select-wrap .action-select[disabled]{color:#333}.action-select-wrap .action-select[disabled]:after{border-color:#333 transparent transparent}.action-select-wrap._active{z-index:500}.action-select-wrap._active .action-select,.action-select-wrap._active .action-select:before{border-color:#007bdb}.action-select-wrap._active .action-select:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-select-wrap .abs-action-menu .action-submenu,.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu,.action-select-wrap .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:45rem;overflow-y:auto}.action-select-wrap .abs-action-menu .action-submenu ._disabled:hover,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .action-menu ._disabled:hover,.action-select-wrap .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled:hover,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled:hover{background:#fff}.action-select-wrap .abs-action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .abs-action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .action-menu ._disabled .action-menu-item,.action-select-wrap .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu ._disabled .action-menu-item,.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu ._disabled .action-menu-item{cursor:default;opacity:.5}.action-select-wrap .action-menu-items{left:0;position:absolute;right:0;top:100%}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu{min-width:100%;position:static}.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.abs-action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu,.action-select-wrap .action-menu-items>.action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .action-menu .action-submenu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu,.action-select-wrap .action-menu-items>.actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{position:absolute}.action-multicheck-wrap{display:inline-block;height:1.6rem;padding-top:1px;position:relative;width:3.1rem;z-index:200}.action-multicheck-wrap:hover .action-multicheck-toggle,.action-multicheck-wrap:hover .admin__control-checkbox+label:before{border-color:#878787}.action-multicheck-wrap._active .action-multicheck-toggle,.action-multicheck-wrap._active .admin__control-checkbox+label:before{border-color:#007bdb}.action-multicheck-wrap._active .abs-action-menu .action-submenu,.action-multicheck-wrap._active .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .action-menu,.action-multicheck-wrap._active .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu,.action-multicheck-wrap._active .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap._active .actions-split .dropdown-menu .action-submenu .action-submenu{opacity:1;visibility:visible;display:block}.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{background-color:#fff}.action-multicheck-wrap._disabled .action-multicheck-toggle,.action-multicheck-wrap._disabled .admin__control-checkbox+label:before{border-color:#adadad;opacity:1}.action-multicheck-wrap .action-multicheck-toggle,.action-multicheck-wrap .admin__control-checkbox,.action-multicheck-wrap .admin__control-checkbox+label{float:left}.action-multicheck-wrap .action-multicheck-toggle{border-radius:0 1px 1px 0;height:1.6rem;margin-left:-1px;padding:0;position:relative;transition:border-color .1s linear;width:1.6rem}.action-multicheck-wrap .action-multicheck-toggle._active:after,.action-multicheck-wrap .action-multicheck-toggle.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:after{border-color:#000 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;top:50%;transition:all .2s linear;width:0}._active .action-multicheck-wrap .action-multicheck-toggle:after,.active .action-multicheck-wrap .action-multicheck-toggle:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.action-multicheck-wrap .action-multicheck-toggle:hover:after{border-color:#000 transparent transparent}.action-multicheck-wrap .action-multicheck-toggle:focus{border-color:#007bdb}.action-multicheck-wrap .action-multicheck-toggle:after{right:.3rem}.action-multicheck-wrap .abs-action-menu .action-submenu,.action-multicheck-wrap .abs-action-menu .action-submenu .action-submenu,.action-multicheck-wrap .action-menu,.action-multicheck-wrap .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu,.action-multicheck-wrap .actions-split .action-menu .action-submenu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu,.action-multicheck-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:-1.1rem;margin-top:1px;right:auto;text-align:left}.action-multicheck-wrap .action-menu-item{white-space:nowrap}.admin__action-multiselect-wrap{display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.admin__action-multiselect-wrap.action-select-wrap:focus{box-shadow:none}.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .action-menu,.admin__action-multiselect-wrap.action-select-wrap .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-wrap.action-select-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:none;overflow-y:inherit}.admin__action-multiselect-wrap .action-menu-item{transition:background-color .1s linear}.admin__action-multiselect-wrap .action-menu-item._selected{background-color:#e0f6fe}.admin__action-multiselect-wrap .action-menu-item._hover{background-color:#e3e3e3}.admin__action-multiselect-wrap .action-menu-item._unclickable{cursor:default}.admin__action-multiselect-wrap .admin__action-multiselect{border:1px solid #adadad;cursor:pointer;display:block;min-height:3.2rem;padding-right:3.6rem;white-space:normal}.admin__action-multiselect-wrap .admin__action-multiselect:after{bottom:1.25rem;top:auto}.admin__action-multiselect-wrap .admin__action-multiselect:before{height:3.3rem;top:auto}.admin__control-table-wrapper .admin__action-multiselect-wrap{position:static}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect{position:relative}.admin__control-table-wrapper .admin__action-multiselect-wrap .admin__action-multiselect:before{right:-1px;top:-1px}.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .abs-action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu,.admin__control-table-wrapper .admin__action-multiselect-wrap .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .action-menu .action-submenu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu,.admin__control-table-wrapper .admin__action-multiselect-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:34rem;right:auto;top:auto;z-index:1}.admin__action-multiselect-wrap .admin__action-multiselect-item-path{color:#a79d95;font-size:1.2rem;font-weight:400;padding-left:1rem}.admin__action-multiselect-actions-wrap{border-top:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;text-align:center}.admin__action-multiselect-actions-wrap .action-default{font-size:1.3rem;min-width:13rem}.admin__action-multiselect-text{padding:.6rem 1rem}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{text-align:left}.admin__action-multiselect-label{cursor:pointer;position:relative;z-index:1}.admin__action-multiselect-label:before{margin-right:.5rem}._unclickable .admin__action-multiselect-label{cursor:default;font-weight:700}.admin__action-multiselect-search-wrap{border-bottom:1px solid #e3e3e3;margin:0 1rem;padding:1rem 0;position:relative}.admin__action-multiselect-search{padding-right:3rem;width:100%}.admin__action-multiselect-search-label{display:block;font-size:1.5rem;height:1em;overflow:hidden;position:absolute;right:2.2rem;top:1.7rem;width:1em}.admin__action-multiselect-search-label:before{content:'\e60c'}.admin__action-multiselect-search-count{color:#a79d95;margin-top:1rem}.admin__action-multiselect-menu-inner{margin-bottom:0;max-height:46rem;overflow-y:auto}.admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{list-style:none;max-height:none;overflow:hidden;padding-left:2.2rem}.admin__action-multiselect-menu-inner ._hidden{display:none}.admin__action-multiselect-crumb{background-color:#f5f5f5;border:1px solid #a79d95;border-radius:1px;display:inline-block;font-size:1.2rem;margin:.3rem -4px .3rem .3rem;padding:.3rem 2.4rem .4rem 1rem;position:relative;transition:border-color .1s linear}.admin__action-multiselect-crumb:hover{border-color:#908379}.admin__action-multiselect-crumb .action-close{bottom:0;font-size:.5em;position:absolute;right:0;top:0;width:2rem}.admin__action-multiselect-crumb .action-close:hover{color:#000}.admin__action-multiselect-crumb .action-close:active,.admin__action-multiselect-crumb .action-close:focus{background-color:transparent}.admin__action-multiselect-crumb .action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__action-multiselect-tree .abs-action-menu .action-submenu,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .action-menu,.admin__action-multiselect-tree .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu{min-width:34.7rem}.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .abs-action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-menu-item,.admin__action-multiselect-tree .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-menu-item,.admin__action-multiselect-tree .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item{margin-top:.1rem}.admin__action-multiselect-tree .action-menu-item{margin-left:4.2rem;position:relative}.admin__action-multiselect-tree .action-menu-item._expended:before{border-left:1px dashed #a79d95;bottom:0;content:'';left:-1rem;position:absolute;top:1rem;width:1px}.admin__action-multiselect-tree .action-menu-item._expended .admin__action-multiselect-dropdown:before{content:'\e615'}.admin__action-multiselect-tree .action-menu-item._with-checkbox .admin__action-multiselect-label{padding-left:2.6rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner{padding-left:3.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner .admin__action-multiselect-menu-inner:before{left:4.3rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item{position:relative}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:last-child:before{height:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after,.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{content:'';left:0;position:absolute}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:after{border-top:1px dashed #a79d95;height:1px;top:2.1rem;width:5.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item:before{border-left:1px dashed #a79d95;height:100%;top:0;width:1px}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._parent:after{width:4.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root{margin-left:-1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:after{left:3.2rem;width:2.2rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:before{left:3.2rem;top:1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root._parent:after{display:none}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:first-child:before{top:2.1rem}.admin__action-multiselect-tree .admin__action-multiselect-menu-inner-item._root:last-child:before{height:1rem}.admin__action-multiselect-tree .admin__action-multiselect-label{line-height:2.2rem;vertical-align:middle;word-break:break-all}.admin__action-multiselect-tree .admin__action-multiselect-label:before{left:0;position:absolute;top:.4rem}.admin__action-multiselect-dropdown{border-radius:50%;height:2.2rem;left:-2.2rem;position:absolute;top:1rem;width:2.2rem;z-index:1}.admin__action-multiselect-dropdown:before{background:#fff;color:#a79d95;content:'\e616';font-size:2.2rem}.admin__actions-switch{display:inline-block;position:relative;vertical-align:middle}.admin__field-control .admin__actions-switch{line-height:3.2rem}.admin__actions-switch+.admin__field-service{min-width:34rem}._disabled .admin__actions-switch-checkbox+.admin__actions-switch-label,.admin__actions-switch-checkbox.disabled+.admin__actions-switch-label{cursor:not-allowed;opacity:.5;pointer-events:none}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:before{left:15px}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label:after{background:#79a22e}.admin__actions-switch-checkbox:checked+.admin__actions-switch-label .admin__actions-switch-text:before{content:attr(data-text-on)}.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:after,.admin__actions-switch-checkbox:focus+.admin__actions-switch-label:before{border-color:#007bdb}._error .admin__actions-switch-checkbox+.admin__actions-switch-label:after,._error .admin__actions-switch-checkbox+.admin__actions-switch-label:before{border-color:#e22626}.admin__actions-switch-label{cursor:pointer;display:inline-block;height:22px;line-height:22px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.admin__actions-switch-label:after,.admin__actions-switch-label:before{left:0;position:absolute;right:auto;top:0}.admin__actions-switch-label:before{background:#fff;border:1px solid #aaa6a0;border-radius:100%;content:'';display:block;height:22px;transition:left .2s ease-in 0s;width:22px;z-index:1}.admin__actions-switch-label:after{background:#e3e3e3;border:1px solid #aaa6a0;border-radius:12px;content:'';display:block;height:22px;transition:background .2s ease-in 0s;vertical-align:middle;width:37px;z-index:0}.admin__actions-switch-text:before{content:attr(data-text-off);padding-left:47px;white-space:nowrap}.abs-action-delete,.abs-action-reset,.action-close,.admin__field-fallback-reset,.extensions-information .list .extension-delete,.notifications-close,.search-global-field._active .search-global-action{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0}.abs-action-delete:hover,.abs-action-reset:hover,.action-close:hover,.admin__field-fallback-reset:hover,.extensions-information .list .extension-delete:hover,.notifications-close:hover,.search-global-field._active .search-global-action:hover{background-color:transparent;border:none;box-shadow:none}.abs-action-default,.abs-action-pattern,.abs-action-primary,.abs-action-quaternary,.abs-action-secondary,.abs-action-tertiary,.action-default,.action-primary,.action-quaternary,.action-secondary,.action-tertiary,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions>button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary,button,button.primary,button.secondary,button.tertiary{border:1px solid;border-radius:0;display:inline-block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:1.36;padding:.6rem 1em;text-align:center;vertical-align:baseline}.abs-action-default.disabled,.abs-action-default[disabled],.abs-action-pattern.disabled,.abs-action-pattern[disabled],.abs-action-primary.disabled,.abs-action-primary[disabled],.abs-action-quaternary.disabled,.abs-action-quaternary[disabled],.abs-action-secondary.disabled,.abs-action-secondary[disabled],.abs-action-tertiary.disabled,.abs-action-tertiary[disabled],.action-default.disabled,.action-default[disabled],.action-primary.disabled,.action-primary[disabled],.action-quaternary.disabled,.action-quaternary[disabled],.action-secondary.disabled,.action-secondary[disabled],.action-tertiary.disabled,.action-tertiary[disabled],.modal-popup .modal-footer .action-primary.disabled,.modal-popup .modal-footer .action-primary[disabled],.modal-popup .modal-footer .action-secondary.disabled,.modal-popup .modal-footer .action-secondary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.action-secondary.disabled,.page-actions .page-actions-buttons>button.action-secondary[disabled],.page-actions .page-actions-buttons>button.disabled,.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions .page-actions-buttons>button[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.action-secondary.disabled,.page-actions>button.action-secondary[disabled],.page-actions>button.disabled,.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],.page-actions>button[disabled],button.disabled,button.primary.disabled,button.primary[disabled],button.secondary.disabled,button.secondary[disabled],button.tertiary.disabled,button.tertiary[disabled],button[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-l,.modal-popup .modal-footer .action-primary,.modal-popup .modal-footer .action-secondary,.page-actions .page-actions-buttons>button,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions .page-actions-buttons>button.primary,.page-actions button,.page-actions>button.action-primary,.page-actions>button.action-secondary,.page-actions>button.primary{font-size:1.6rem;letter-spacing:.025em;padding-bottom:.6875em;padding-top:.6875em}.abs-action-delete,.extensions-information .list .extension-delete{display:inline-block;font-size:1.6rem;margin-left:1.2rem;padding-top:.7rem;text-decoration:none;vertical-align:middle}.abs-action-delete:after,.extensions-information .list .extension-delete:after{color:#666;content:'\e630'}.abs-action-delete:hover:after,.extensions-information .list .extension-delete:hover:after{color:#35302c}.abs-action-button-as-link,.action-advanced,.data-grid .action-delete{line-height:1.36;padding:0;color:#008bdb;text-decoration:none;background:0 0;border:0;display:inline;font-weight:400;border-radius:0}.abs-action-button-as-link:visited,.action-advanced:visited,.data-grid .action-delete:visited{color:#008bdb;text-decoration:none}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{text-decoration:underline}.abs-action-button-as-link:active,.action-advanced:active,.data-grid .action-delete:active{color:#ff5501;text-decoration:underline}.abs-action-button-as-link:hover,.action-advanced:hover,.data-grid .action-delete:hover{color:#0fa7ff}.abs-action-button-as-link:active,.abs-action-button-as-link:focus,.abs-action-button-as-link:hover,.action-advanced:active,.action-advanced:focus,.action-advanced:hover,.data-grid .action-delete:active,.data-grid .action-delete:focus,.data-grid .action-delete:hover{background:0 0;border:0}.abs-action-button-as-link.disabled,.abs-action-button-as-link[disabled],.action-advanced.disabled,.action-advanced[disabled],.data-grid .action-delete.disabled,.data-grid .action-delete[disabled],fieldset[disabled] .abs-action-button-as-link,fieldset[disabled] .action-advanced,fieldset[disabled] .data-grid .action-delete{color:#008bdb;opacity:.5;cursor:default;pointer-events:none;text-decoration:underline}.abs-action-button-as-link:active,.abs-action-button-as-link:not(:focus),.action-advanced:active,.action-advanced:not(:focus),.data-grid .action-delete:active,.data-grid .action-delete:not(:focus){box-shadow:none}.abs-action-button-as-link:focus,.action-advanced:focus,.data-grid .action-delete:focus{color:#0fa7ff}.abs-action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.abs-action-default:active,.abs-action-default:focus,.abs-action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.abs-action-primary,.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary,button.primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.abs-action-primary:active,.abs-action-primary:focus,.abs-action-primary:hover,.page-actions .page-actions-buttons>button.action-primary:active,.page-actions .page-actions-buttons>button.action-primary:focus,.page-actions .page-actions-buttons>button.action-primary:hover,.page-actions .page-actions-buttons>button.primary:active,.page-actions .page-actions-buttons>button.primary:focus,.page-actions .page-actions-buttons>button.primary:hover,.page-actions>button.action-primary:active,.page-actions>button.action-primary:focus,.page-actions>button.action-primary:hover,.page-actions>button.primary:active,.page-actions>button.primary:focus,.page-actions>button.primary:hover,button.primary:active,button.primary:focus,button.primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-primary.disabled,.abs-action-primary[disabled],.page-actions .page-actions-buttons>button.action-primary.disabled,.page-actions .page-actions-buttons>button.action-primary[disabled],.page-actions .page-actions-buttons>button.primary.disabled,.page-actions .page-actions-buttons>button.primary[disabled],.page-actions>button.action-primary.disabled,.page-actions>button.action-primary[disabled],.page-actions>button.primary.disabled,.page-actions>button.primary[disabled],button.primary.disabled,button.primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.abs-action-secondary,.modal-popup .modal-footer .action-primary,.page-actions .page-actions-buttons>button.action-secondary,.page-actions>button.action-secondary,button.secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.abs-action-secondary:active,.abs-action-secondary:focus,.abs-action-secondary:hover,.modal-popup .modal-footer .action-primary:active,.modal-popup .modal-footer .action-primary:focus,.modal-popup .modal-footer .action-primary:hover,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions .page-actions-buttons>button.action-secondary:focus,.page-actions .page-actions-buttons>button.action-secondary:hover,.page-actions>button.action-secondary:active,.page-actions>button.action-secondary:focus,.page-actions>button.action-secondary:hover,button.secondary:active,button.secondary:focus,button.secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.abs-action-secondary:active,.modal-popup .modal-footer .action-primary:active,.page-actions .page-actions-buttons>button.action-secondary:active,.page-actions>button.action-secondary:active,button.secondary:active{background-color:#35302c}.abs-action-tertiary,.modal-popup .modal-footer .action-secondary,button.tertiary{background-color:transparent;border-color:transparent;text-shadow:none;color:#008bdb}.abs-action-tertiary:active,.abs-action-tertiary:focus,.abs-action-tertiary:hover,.modal-popup .modal-footer .action-secondary:active,.modal-popup .modal-footer .action-secondary:focus,.modal-popup .modal-footer .action-secondary:hover,button.tertiary:active,button.tertiary:focus,button.tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#0fa7ff;text-decoration:underline}.abs-action-quaternary,.page-actions .page-actions-buttons>button,.page-actions>button{background-color:transparent;border-color:transparent;text-shadow:none;color:#333}.abs-action-quaternary:active,.abs-action-quaternary:focus,.abs-action-quaternary:hover,.page-actions .page-actions-buttons>button:active,.page-actions .page-actions-buttons>button:focus,.page-actions .page-actions-buttons>button:hover,.page-actions>button:active,.page-actions>button:focus,.page-actions>button:hover{background-color:transparent;border-color:transparent;box-shadow:none;color:#1a1a1a}.abs-action-menu,.actions-split .abs-action-menu .action-submenu,.actions-split .abs-action-menu .action-submenu .action-submenu,.actions-split .action-menu,.actions-split .action-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.actions-split .dropdown-menu{text-align:left;background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu._active,.actions-split .abs-action-menu .action-submenu .action-submenu._active,.actions-split .abs-action-menu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .action-menu._active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .actions-split .dropdown-menu .action-submenu._active,.actions-split .dropdown-menu._active{display:block}.abs-action-menu>li,.actions-split .abs-action-menu .action-submenu .action-submenu>li,.actions-split .abs-action-menu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .action-menu>li,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .actions-split .dropdown-menu .action-submenu>li,.actions-split .dropdown-menu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu>li>a:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .abs-action-menu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .action-menu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu>li>a:hover{text-decoration:none}.abs-action-menu>li._visible,.abs-action-menu>li:hover,.actions-split .abs-action-menu .action-submenu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu .action-submenu>li:hover,.actions-split .abs-action-menu .action-submenu>li._visible,.actions-split .abs-action-menu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .action-menu>li._visible,.actions-split .action-menu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .actions-split .dropdown-menu .action-submenu>li:hover,.actions-split .dropdown-menu>li._visible,.actions-split .dropdown-menu>li:hover{background-color:#e3e3e3}.abs-action-menu>li:active,.actions-split .abs-action-menu .action-submenu .action-submenu>li:active,.actions-split .abs-action-menu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .action-menu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .actions-split .dropdown-menu .action-submenu>li:active,.actions-split .dropdown-menu>li:active{background-color:#cacaca}.abs-action-menu>li._parent,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent,.actions-split .abs-action-menu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .action-menu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent,.actions-split .dropdown-menu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .abs-action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-menu-item,.abs-action-menu .item,.actions-split .abs-action-menu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu .item,.actions-split .abs-action-menu .action-submenu .item,.actions-split .action-menu .action-menu-item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .item,.actions-split .action-menu .item,.actions-split .actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .actions-split .dropdown-menu .action-submenu .item,.actions-split .dropdown-menu .action-menu-item,.actions-split .dropdown-menu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu,.ie9 .actions-split .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu a.action-menu-item,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .abs-action-menu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .action-menu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu a.action-menu-item{color:#333}.abs-action-menu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .abs-action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .action-menu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .actions-split .dropdown-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.abs-action-wrap-triangle{position:relative}.abs-action-wrap-triangle .action-default{width:100%}.abs-action-wrap-triangle .action-default:after,.abs-action-wrap-triangle .action-default:before{border-style:solid;content:'';height:0;position:absolute;top:0;width:0}.abs-action-wrap-triangle .action-default:active,.abs-action-wrap-triangle .action-default:focus,.abs-action-wrap-triangle .action-default:hover{box-shadow:none}._keyfocus .abs-action-wrap-triangle .action-default:focus{box-shadow:0 0 0 1px #007bdb}.ie10 .abs-action-wrap-triangle .action-default.disabled,.ie10 .abs-action-wrap-triangle .action-default[disabled],.ie9 .abs-action-wrap-triangle .action-default.disabled,.ie9 .abs-action-wrap-triangle .action-default[disabled]{background-color:#fcfcfc;opacity:1;text-shadow:none}.abs-action-wrap-triangle-right{display:inline-block;padding-right:1.6rem;position:relative}.abs-action-wrap-triangle-right .action-default:after,.abs-action-wrap-triangle-right .action-default:before{border-color:transparent transparent transparent #e3e3e3;border-width:1.7rem 0 1.6rem 1.7rem;left:100%;margin-left:-1.7rem}.abs-action-wrap-triangle-right .action-default:before{border-left-color:#949494;right:-1px}.abs-action-wrap-triangle-right .action-default:active:after,.abs-action-wrap-triangle-right .action-default:focus:after,.abs-action-wrap-triangle-right .action-default:hover:after{border-left-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-right .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-right .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-right .action-default[disabled]:after{border-color:transparent transparent transparent #fcfcfc}.abs-action-wrap-triangle-right .action-primary:after{border-color:transparent transparent transparent #eb5202}.abs-action-wrap-triangle-right .action-primary:active:after,.abs-action-wrap-triangle-right .action-primary:focus:after,.abs-action-wrap-triangle-right .action-primary:hover:after{border-left-color:#ba4000}.abs-action-wrap-triangle-left{display:inline-block;padding-left:1.6rem}.abs-action-wrap-triangle-left .action-default{text-indent:-.85rem}.abs-action-wrap-triangle-left .action-default:after,.abs-action-wrap-triangle-left .action-default:before{border-color:transparent #e3e3e3 transparent transparent;border-width:1.7rem 1.7rem 1.6rem 0;margin-right:-1.7rem;right:100%}.abs-action-wrap-triangle-left .action-default:before{border-right-color:#949494;left:-1px}.abs-action-wrap-triangle-left .action-default:active:after,.abs-action-wrap-triangle-left .action-default:focus:after,.abs-action-wrap-triangle-left .action-default:hover:after{border-right-color:#dbdbdb}.ie10 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie10 .abs-action-wrap-triangle-left .action-default[disabled]:after,.ie9 .abs-action-wrap-triangle-left .action-default.disabled:after,.ie9 .abs-action-wrap-triangle-left .action-default[disabled]:after{border-color:transparent #fcfcfc transparent transparent}.abs-action-wrap-triangle-left .action-primary:after{border-color:transparent #eb5202 transparent transparent}.abs-action-wrap-triangle-left .action-primary:active:after,.abs-action-wrap-triangle-left .action-primary:focus:after,.abs-action-wrap-triangle-left .action-primary:hover:after{border-right-color:#ba4000}.action-default,button{background:#e3e3e3;border-color:#adadad;color:#514943}.action-default:active,.action-default:focus,.action-default:hover,button:active,button:focus,button:hover{background-color:#dbdbdb;color:#514943;text-decoration:none}.action-primary{background-color:#eb5202;border-color:#eb5202;color:#fff;text-shadow:1px 1px 0 rgba(0,0,0,.25)}.action-primary:active,.action-primary:focus,.action-primary:hover{background-color:#ba4000;border-color:#b84002;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-primary.disabled,.action-primary[disabled]{cursor:default;opacity:.5;pointer-events:none}.action-secondary{background-color:#514943;border-color:#514943;color:#fff;text-shadow:1px 1px 1px rgba(0,0,0,.3)}.action-secondary:active,.action-secondary:focus,.action-secondary:hover{background-color:#35302c;border-color:#35302c;box-shadow:0 0 0 1px #007bdb;color:#fff;text-decoration:none}.action-secondary:active{background-color:#35302c}.action-quaternary,.action-tertiary{background-color:transparent;border-color:transparent;text-shadow:none}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover,.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{background-color:transparent;border-color:transparent;box-shadow:none}.action-tertiary{color:#008bdb}.action-tertiary:active,.action-tertiary:focus,.action-tertiary:hover{color:#0fa7ff;text-decoration:underline}.action-quaternary{color:#333}.action-quaternary:active,.action-quaternary:focus,.action-quaternary:hover{color:#1a1a1a}.action-close>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-close:active{-ms-transform:scale(0.9);transform:scale(0.9)}.action-close:before{content:'\e62f';transition:color .1s linear}.action-close:hover{cursor:pointer;text-decoration:none}.abs-action-menu .action-submenu,.abs-action-menu .action-submenu .action-submenu,.action-menu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{background-color:#fff;border:1px solid #007bdb;border-radius:1px;box-shadow:1px 1px 5px rgba(0,0,0,.5);color:#333;display:none;font-weight:400;left:0;list-style:none;margin:2px 0 0;min-width:0;padding:0;position:absolute;right:0;top:100%}.abs-action-menu .action-submenu .action-submenu._active,.abs-action-menu .action-submenu._active,.action-menu .action-submenu._active,.action-menu._active,.actions-split .action-menu .action-submenu .action-submenu._active,.actions-split .action-menu .action-submenu._active,.actions-split .dropdown-menu .action-submenu .action-submenu._active,.actions-split .dropdown-menu .action-submenu._active{display:block}.abs-action-menu .action-submenu .action-submenu>li,.abs-action-menu .action-submenu>li,.action-menu .action-submenu>li,.action-menu>li,.actions-split .action-menu .action-submenu .action-submenu>li,.actions-split .action-menu .action-submenu>li,.actions-split .dropdown-menu .action-submenu .action-submenu>li,.actions-split .dropdown-menu .action-submenu>li{border:none;display:block;padding:0;transition:background-color .1s linear}.abs-action-menu .action-submenu .action-submenu>li>a:hover,.abs-action-menu .action-submenu>li>a:hover,.action-menu .action-submenu>li>a:hover,.action-menu>li>a:hover,.actions-split .action-menu .action-submenu .action-submenu>li>a:hover,.actions-split .action-menu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li>a:hover,.actions-split .dropdown-menu .action-submenu>li>a:hover{text-decoration:none}.abs-action-menu .action-submenu .action-submenu>li._visible,.abs-action-menu .action-submenu .action-submenu>li:hover,.abs-action-menu .action-submenu>li._visible,.abs-action-menu .action-submenu>li:hover,.action-menu .action-submenu>li._visible,.action-menu .action-submenu>li:hover,.action-menu>li._visible,.action-menu>li:hover,.actions-split .action-menu .action-submenu .action-submenu>li._visible,.actions-split .action-menu .action-submenu .action-submenu>li:hover,.actions-split .action-menu .action-submenu>li._visible,.actions-split .action-menu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu .action-submenu>li:hover,.actions-split .dropdown-menu .action-submenu>li._visible,.actions-split .dropdown-menu .action-submenu>li:hover{background-color:#e3e3e3}.abs-action-menu .action-submenu .action-submenu>li:active,.abs-action-menu .action-submenu>li:active,.action-menu .action-submenu>li:active,.action-menu>li:active,.actions-split .action-menu .action-submenu .action-submenu>li:active,.actions-split .action-menu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu .action-submenu>li:active,.actions-split .dropdown-menu .action-submenu>li:active{background-color:#cacaca}.abs-action-menu .action-submenu .action-submenu>li._parent,.abs-action-menu .action-submenu>li._parent,.action-menu .action-submenu>li._parent,.action-menu>li._parent,.actions-split .action-menu .action-submenu .action-submenu>li._parent,.actions-split .action-menu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent,.actions-split .dropdown-menu .action-submenu>li._parent{-webkit-flex-direction:row;display:flex;-ms-flex-direction:row;flex-direction:row}.abs-action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.abs-action-menu .action-submenu>li._parent>.action-menu-item,.action-menu .action-submenu>li._parent>.action-menu-item,.action-menu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .action-menu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu>li._parent>.action-menu-item,.actions-split .dropdown-menu .action-submenu>li._parent>.action-menu-item{min-width:100%}.abs-action-menu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .action-menu-item,.abs-action-menu .action-submenu .action-submenu .item,.abs-action-menu .action-submenu .item,.action-menu .action-menu-item,.action-menu .action-submenu .action-menu-item,.action-menu .action-submenu .item,.action-menu .item,.actions-split .action-menu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .action-menu-item,.actions-split .action-menu .action-submenu .action-submenu .item,.actions-split .action-menu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu .item,.actions-split .dropdown-menu .action-submenu .item{cursor:pointer;display:block;padding:.6875em 1em}.abs-action-menu .action-submenu .action-submenu,.action-menu .action-submenu,.actions-split .action-menu .action-submenu .action-submenu,.actions-split .dropdown-menu .action-submenu .action-submenu{bottom:auto;left:auto;margin-left:0;margin-top:-1px;position:absolute;right:auto;top:auto}.ie9 .abs-action-menu .action-submenu .action-submenu,.ie9 .abs-action-menu .action-submenu .action-submenu .action-submenu,.ie9 .action-menu .action-submenu,.ie9 .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu,.ie9 .actions-split .action-menu .action-submenu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu,.ie9 .actions-split .dropdown-menu .action-submenu .action-submenu .action-submenu{margin-left:99%;margin-top:-3.5rem}.abs-action-menu .action-submenu .action-submenu a.action-menu-item,.abs-action-menu .action-submenu a.action-menu-item,.action-menu .action-submenu a.action-menu-item,.action-menu a.action-menu-item,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .action-menu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item,.actions-split .dropdown-menu .action-submenu a.action-menu-item{color:#333}.abs-action-menu .action-submenu .action-submenu a.action-menu-item:focus,.abs-action-menu .action-submenu a.action-menu-item:focus,.action-menu .action-submenu a.action-menu-item:focus,.action-menu a.action-menu-item:focus,.actions-split .action-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .action-menu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu .action-submenu a.action-menu-item:focus,.actions-split .dropdown-menu .action-submenu a.action-menu-item:focus{background-color:#e3e3e3;box-shadow:none}.messages .message:last-child{margin:0 0 2rem}.message{background:#fffbbb;border:none;border-radius:0;color:#333;font-size:1.4rem;margin:0 0 1px;padding:1.8rem 4rem 1.8rem 5.5rem;position:relative;text-shadow:none}.message:before{background:0 0;border:0;color:#007bdb;content:'\e61a';font-family:Icons;font-size:1.9rem;font-style:normal;font-weight:400;height:auto;left:1.9rem;line-height:inherit;margin-top:-1.3rem;position:absolute;speak:none;text-shadow:none;top:50%;width:auto}.message-notice:before{color:#007bdb;content:'\e61a'}.message-warning:before{color:#eb5202;content:'\e623'}.message-error{background:#fcc}.message-error:before{color:#e22626;content:'\e632';font-size:1.5rem;left:2.2rem;margin-top:-1rem}.message-success:before{color:#79a22e;content:'\e62d'}.message-spinner:before{display:none}.message-spinner .spinner{font-size:2.5rem;left:1.5rem;position:absolute;top:1.5rem}.message-in-rating-edit{margin-left:1.8rem;margin-right:1.8rem}.modal-popup .action-close,.modal-slide .action-close{color:#736963;position:absolute;right:0;top:0;z-index:1}.modal-popup .action-close:active,.modal-slide .action-close:active{-ms-transform:none;transform:none}.modal-popup .action-close:active:before,.modal-slide .action-close:active:before{font-size:1.8rem}.modal-popup .action-close:hover:before,.modal-slide .action-close:hover:before{color:#58504b}.modal-popup .action-close:before,.modal-slide .action-close:before{font-size:2rem}.modal-popup .action-close:focus,.modal-slide .action-close:focus{background-color:transparent}.modal-popup.prompt .prompt-message{padding:2rem 0}.modal-popup.prompt .prompt-message input{width:100%}.modal-popup.confirm .modal-inner-wrap .message,.modal-popup.prompt .modal-inner-wrap .message{background:#fff}.modal-popup.modal-system-messages .modal-inner-wrap{background:#fffbbb}.modal-popup._image-box .modal-inner-wrap{margin:5rem auto;max-width:78rem;position:static}.modal-popup._image-box .thumbnail-preview{padding-bottom:3rem;text-align:center}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image-block{border:1px solid #ccc;margin:0 auto 2rem;max-width:58rem;padding:2rem}.modal-popup._image-box .thumbnail-preview .thumbnail-preview-image{max-height:54rem}.modal-popup .modal-title{font-size:2.4rem;margin-right:6.4rem}.modal-popup .modal-footer{padding-top:2.6rem;text-align:right}.modal-popup .action-close{padding:3rem}.modal-popup .action-close:active,.modal-popup .action-close:focus{background:0 0;padding-right:3.1rem;padding-top:3.1rem}.modal-slide .modal-content-new-attribute{-webkit-overflow-scrolling:touch;overflow:auto;padding-bottom:0}.modal-slide .modal-content-new-attribute iframe{margin-bottom:-2.5rem}.modal-slide .modal-title{font-size:2.1rem;margin-right:5.7rem}.modal-slide .action-close{padding:2.1rem 2.6rem}.modal-slide .action-close:active{padding-right:2.7rem;padding-top:2.2rem}.modal-slide .page-main-actions{margin-bottom:.6rem;margin-top:2.1rem}.modal-slide .magento-message{padding:0 3rem 3rem;position:relative}.modal-slide .magento-message .insert-title-inner,.modal-slide .main-col .insert-title-inner{border-bottom:1px solid #adadad;margin:0 0 2rem;padding-bottom:.5rem}.modal-slide .magento-message .insert-actions,.modal-slide .main-col .insert-actions{float:right}.modal-slide .magento-message .title,.modal-slide .main-col .title{font-size:1.6rem;padding-top:.5rem}.modal-slide .main-col,.modal-slide .side-col{float:left;padding-bottom:0}.modal-slide .main-col:after,.modal-slide .side-col:after{display:none}.modal-slide .side-col{width:20%}.modal-slide .main-col{padding-right:0;width:80%}.modal-slide .content-footer .form-buttons{float:right}.modal-title{font-weight:400;margin-bottom:0;min-height:1em}.modal-title span{font-size:1.4rem;font-style:italic;margin-left:1rem}.spinner{display:inline-block;font-size:4rem;height:1em;margin-right:1.5rem;position:relative;width:1em}.spinner>span:nth-child(1){animation-delay:.27s;-ms-transform:rotate(-315deg);transform:rotate(-315deg)}.spinner>span:nth-child(2){animation-delay:.36s;-ms-transform:rotate(-270deg);transform:rotate(-270deg)}.spinner>span:nth-child(3){animation-delay:.45s;-ms-transform:rotate(-225deg);transform:rotate(-225deg)}.spinner>span:nth-child(4){animation-delay:.54s;-ms-transform:rotate(-180deg);transform:rotate(-180deg)}.spinner>span:nth-child(5){animation-delay:.63s;-ms-transform:rotate(-135deg);transform:rotate(-135deg)}.spinner>span:nth-child(6){animation-delay:.72s;-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.spinner>span:nth-child(7){animation-delay:.81s;-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.spinner>span:nth-child(8){animation-delay:.9;-ms-transform:rotate(0deg);transform:rotate(0deg)}@keyframes fade{0%{background-color:#514943}100%{background-color:#fff}}.spinner>span{-ms-transform:scale(0.4);transform:scale(0.4);animation-name:fade;animation-duration:.72s;animation-iteration-count:infinite;animation-direction:linear;background-color:#fff;border-radius:6px;clip:rect(0 .28571429em .1em 0);height:.1em;margin-top:.5em;position:absolute;width:1em}.ie9 .spinner{background:url(../images/ajax-loader.gif) center no-repeat}.ie9 .spinner>span{display:none}.popup-loading{background:rgba(255,255,255,.8);border-color:#ef672f;color:#ef672f;font-size:14px;font-weight:700;left:50%;margin-left:-100px;padding:100px 0 10px;position:fixed;text-align:center;top:40%;width:200px;z-index:1003}.popup-loading:after{background-image:url(../images/loader-1.gif);content:'';height:64px;left:50%;margin:-32px 0 0 -32px;position:absolute;top:40%;width:64px;z-index:2}.loading-mask,.loading-old{background:rgba(255,255,255,.4);bottom:0;left:0;position:fixed;right:0;top:0;z-index:2003}.loading-mask img,.loading-old img{display:none}.loading-mask p,.loading-old p{margin-top:118px}.loading-mask .loader,.loading-old .loader{background:url(../images/loader-1.gif) 50% 30% no-repeat #f7f3eb;border-radius:5px;bottom:0;color:#575757;font-size:14px;font-weight:700;height:160px;left:0;margin:auto;opacity:.95;position:absolute;right:0;text-align:center;top:0;width:160px}.admin-user{float:right;line-height:1.36;margin-left:.3rem;z-index:490}.admin-user._active .admin__action-dropdown,.admin-user.active .admin__action-dropdown{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.admin-user .admin__action-dropdown{height:3.3rem;padding:.7rem 2.8rem .4rem 4rem}.admin-user .admin__action-dropdown._active:after,.admin-user .admin__action-dropdown.active:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:after{border-color:#777 transparent transparent;border-style:solid;border-width:.5rem .4rem 0;content:'';height:0;margin-top:-.2rem;position:absolute;right:1.3rem;top:50%;transition:all .2s linear;width:0}._active .admin-user .admin__action-dropdown:after,.active .admin-user .admin__action-dropdown:after{-ms-transform:rotate(180deg);transform:rotate(180deg)}.admin-user .admin__action-dropdown:hover:after{border-color:#000 transparent transparent}.admin-user .admin__action-dropdown:before{color:#777;content:'\e600';font-size:2rem;left:1.1rem;margin-top:-1.1rem;position:absolute;top:50%}.admin-user .admin__action-dropdown:hover:before{color:#333}.admin-user .admin__action-dropdown-menu{min-width:20rem;padding-left:1rem;padding-right:1rem}.admin-user .admin__action-dropdown-menu>li>a{padding-left:.5em;padding-right:1.8rem;transition:background-color .1s linear;white-space:nowrap}.admin-user .admin__action-dropdown-menu>li>a:hover{background-color:#e0f6fe;color:#333}.admin-user .admin__action-dropdown-menu>li>a:active{background-color:#c7effd;bottom:-1px;position:relative}.admin-user .admin__action-dropdown-menu .admin-user-name{text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:20rem;overflow:hidden;vertical-align:top}.admin-user-account-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;max-width:11.2rem}.search-global{float:right;margin-right:-.3rem;position:relative;z-index:480}.search-global-field{min-width:5rem}.search-global-field._active .search-global-input{background-color:#fff;border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5);padding-right:4rem;width:25rem}.search-global-field._active .search-global-action{display:block;height:3.3rem;position:absolute;right:0;text-indent:-100%;top:0;width:5rem;z-index:3}.search-global-field .autocomplete-results{height:3.3rem;position:absolute;right:0;top:0;width:25rem}.search-global-field .search-global-menu{border:1px solid #007bdb;border-top-color:transparent;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin-top:-2px;padding:0;position:absolute;right:0;top:100%;z-index:2}.search-global-field .search-global-menu:after{background-color:#fff;content:'';height:5px;left:0;position:absolute;right:0;top:-5px}.search-global-field .search-global-menu>li{background-color:#fff;border-top:1px solid #ddd;display:block;font-size:1.2rem;padding:.75rem 1.4rem .55rem}.search-global-field .search-global-menu>li._active{background-color:#e0f6fe}.search-global-field .search-global-menu .title{display:block;font-size:1.4rem}.search-global-field .search-global-menu .type{color:#1a1a1a;display:block}.search-global-label{cursor:pointer;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;z-index:2}.search-global-label:active{-ms-transform:scale(0.9);transform:scale(0.9)}.search-global-label:hover:before{color:#000}.search-global-label:before{color:#777;content:'\e60c';font-size:2rem}.search-global-input{background-color:transparent;border:1px solid transparent;font-size:1.4rem;height:3.3rem;padding:.75rem 1.4rem .55rem;position:absolute;right:0;top:0;transition:all .1s linear,width .3s linear;width:5rem;z-index:1}.search-global-action{display:none}.notifications-wrapper{float:right;line-height:1;position:relative}.notifications-wrapper.active{z-index:500}.notifications-wrapper.active .notifications-action{border-color:#007bdb;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.notifications-wrapper.active .notifications-action:after{background-color:#fff;border:none;content:'';display:block;height:6px;left:-6px;margin-top:0;position:absolute;right:0;top:100%;width:auto}.notifications-wrapper .admin__action-dropdown-menu{padding:1rem 0 0;width:32rem}.notifications-action{color:#777;height:3.3rem;padding:.75rem 2rem .65rem}.notifications-action:after{display:none}.notifications-action:before{content:'\e607';font-size:1.9rem;margin-right:0}.notifications-action:active:before{position:relative;top:1px}.notifications-action .notifications-counter{background-color:#e22626;border-radius:1em;color:#fff;display:inline-block;font-size:1.1rem;font-weight:700;left:50%;margin-left:.3em;margin-top:-1.1em;padding:.3em .5em;position:absolute;top:50%}.notifications-entry{line-height:1.36;padding:.6rem 2rem .8rem;position:relative;transition:background-color .1s linear}.notifications-entry:hover{background-color:#e0f6fe}.notifications-entry.notifications-entry-last{margin:0 2rem;padding:.3rem 0 1.3rem;text-align:center}.notifications-entry.notifications-entry-last:hover{background-color:transparent}.notifications-entry+.notifications-entry-last{border-top:1px solid #ddd;padding-bottom:.6rem}.notifications-entry ._cutted{cursor:pointer}.notifications-entry ._cutted .notifications-entry-description-start:after{content:'...'}.notifications-entry-title{color:#ef672f;display:block;font-size:1.1rem;font-weight:700;margin-bottom:.7rem;margin-right:1em}.notifications-entry-description{color:#333;font-size:1.1rem;margin-bottom:.8rem}.notifications-entry-description-end{display:none}.notifications-entry-description-end._show{display:inline}.notifications-entry-time{color:#777;font-size:1.1rem}.notifications-close{line-height:1;padding:1rem;position:absolute;right:0;top:.6rem}.notifications-close:before{color:#ccc;content:'\e620';transition:color .1s linear}.notifications-close:hover:before{color:#b3b3b3}.notifications-close:active{-ms-transform:scale(0.95);transform:scale(0.95)}.page-header-actions{padding-top:1.1rem}.page-header-hgroup{padding-right:1.5rem}.page-title{color:#333;font-size:2.8rem}.page-header{padding:1.5rem 3rem}.menu-wrapper{display:inline-block;position:relative;width:8.8rem;z-index:700}.menu-wrapper:before{background-color:#373330;bottom:0;content:'';left:0;position:fixed;top:0;width:8.8rem;z-index:699}.menu-wrapper._fixed{left:0;position:fixed;top:0}.menu-wrapper._fixed~.page-wrapper{margin-left:8.8rem}.menu-wrapper .logo{display:block;height:8.8rem;padding:2.4rem 0 2.2rem;position:relative;text-align:center;z-index:700}._keyfocus .menu-wrapper .logo:focus{background-color:#4a4542;box-shadow:none}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a{background-color:#373330}._keyfocus .menu-wrapper .logo:focus+.admin__menu .level-0:first-child>a:after{display:none}.menu-wrapper .logo:hover .logo-img{-webkit-filter:brightness(1.1);filter:brightness(1.1)}.menu-wrapper .logo:active .logo-img{-ms-transform:scale(0.95);transform:scale(0.95)}.menu-wrapper .logo .logo-img{height:4.2rem;transition:-webkit-filter .2s linear,filter .2s linear,transform .1s linear;width:3.5rem}.abs-menu-separator,.admin__menu .item-partners>a:after,.admin__menu .level-0:first-child>a:after{background-color:#736963;content:'';display:block;height:1px;left:0;margin-left:16%;position:absolute;top:0;width:68%}.admin__menu li{display:block}.admin__menu .level-0:first-child>a{position:relative}.admin__menu .level-0._active>a,.admin__menu .level-0:hover>a{color:#f7f3eb}.admin__menu .level-0._active>a{background-color:#524d49}.admin__menu .level-0:hover>a{background-color:#4a4542}.admin__menu .level-0>a{color:#aaa6a0;display:block;font-size:1rem;letter-spacing:.025em;min-height:6.2rem;padding:1.2rem .5rem .5rem;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;transition:background-color .1s linear;word-wrap:break-word;z-index:700}.admin__menu .level-0>a:focus{box-shadow:none}.admin__menu .level-0>a:before{content:'\e63a';display:block;font-size:2.2rem;height:2.2rem}.admin__menu .level-0>.submenu{background-color:#4a4542;box-shadow:0 0 3px #000;left:100%;min-height:calc(8.8rem + 2rem + 100%);padding:2rem 0 0;position:absolute;top:0;-ms-transform:translateX(-100%);transform:translateX(-100%);transition-duration:.3s;transition-property:transform,visibility;transition-timing-function:ease-in-out;visibility:hidden;z-index:697}.ie10 .admin__menu .level-0>.submenu,.ie11 .admin__menu .level-0>.submenu{height:100%}.admin__menu .level-0._show>.submenu{-ms-transform:translateX(0);transform:translateX(0);visibility:visible;z-index:698}.admin__menu .level-1{margin-left:1.5rem;margin-right:1.5rem}.admin__menu [class*=level-]:not(.level-0) a{display:block;padding:1.25rem 1.5rem}.admin__menu [class*=level-]:not(.level-0) a:hover{background-color:#403934}.admin__menu [class*=level-]:not(.level-0) a:active{background-color:#322c29;padding-bottom:1.15rem;padding-top:1.35rem}.admin__menu .submenu li{min-width:23.8rem}.admin__menu .submenu a{color:#fcfcfc;transition:background-color .1s linear}.admin__menu .submenu a:focus,.admin__menu .submenu a:hover{box-shadow:none;text-decoration:none}._keyfocus .admin__menu .submenu a:focus{background-color:#403934}._keyfocus .admin__menu .submenu a:active{background-color:#322c29}.admin__menu .submenu .parent{margin-bottom:4.5rem}.admin__menu .submenu .parent .submenu-group-title{color:#a79d95;display:block;font-size:1.6rem;font-weight:600;margin-bottom:.7rem;padding:1.25rem 1.5rem;pointer-events:none}.admin__menu .submenu .column{display:table-cell}.admin__menu .submenu-title{color:#fff;display:block;font-size:2.2rem;font-weight:600;margin-bottom:4.2rem;margin-left:3rem;margin-right:5.8rem}.admin__menu .submenu-sub-title{color:#fff;display:block;font-size:1.2rem;margin:-3.8rem 5.8rem 3.8rem 3rem}.admin__menu .action-close{padding:2.4rem 2.8rem;position:absolute;right:0;top:0}.admin__menu .action-close:before{color:#a79d95;font-size:1.7rem}.admin__menu .action-close:hover:before{color:#fff}.admin__menu .item-dashboard>a:before{content:'\e604';font-size:1.8rem;padding-top:.4rem}.admin__menu .item-sales>a:before{content:'\e60b'}.admin__menu .item-catalog>a:before{content:'\e608'}.admin__menu .item-customer>a:before{content:'\e603';font-size:2.6rem;position:relative;top:-.4rem}.admin__menu .item-marketing>a:before{content:'\e609';font-size:2rem;padding-top:.2rem}.admin__menu .item-content>a:before{content:'\e602';font-size:2.4rem;position:relative;top:-.2rem}.admin__menu .item-report>a:before{content:'\e60a'}.admin__menu .item-stores>a:before{content:'\e60d';font-size:1.9rem;padding-top:.3rem}.admin__menu .item-system>a:before{content:'\e610'}.admin__menu .item-partners._active>a:after,.admin__menu .item-system._current+.item-partners>a:after{display:none}.admin__menu .item-partners>a{padding-bottom:1rem}.admin__menu .item-partners>a:before{content:'\e612'}.admin__menu .level-0>.submenu>ul>.level-1:only-of-type>.submenu-group-title,.admin__menu .submenu .column:only-of-type .submenu-group-title{display:none}.admin__menu-overlay{bottom:0;left:0;position:fixed;right:0;top:0;z-index:697}.store-switcher{color:#333;float:left;font-size:1.3rem;margin-top:.7rem}.store-switcher .admin__action-dropdown{background-color:#f8f8f8;margin-left:.5em}.store-switcher .dropdown{display:inline-block;position:relative}.store-switcher .dropdown:after,.store-switcher .dropdown:before{content:'';display:table}.store-switcher .dropdown:after{clear:both}.store-switcher .dropdown .action.toggle{cursor:pointer;display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e607';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle:active:after,.store-switcher .dropdown .action.toggle:hover:after{color:#333}.store-switcher .dropdown .action.toggle.active{display:inline-block;text-decoration:none}.store-switcher .dropdown .action.toggle.active:after{-webkit-font-smoothing:antialiased;font-size:22px;line-height:2;color:#333;content:'\e618';font-family:icons-blank-theme;margin:0;vertical-align:top;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.store-switcher .dropdown .action.toggle.active:active:after,.store-switcher .dropdown .action.toggle.active:hover:after{color:#333}.store-switcher .dropdown .dropdown-menu{margin:4px 0 0;padding:0;list-style:none;background:#fff;border:1px solid #aaa6a0;min-width:19.5rem;z-index:100;box-sizing:border-box;display:none;position:absolute;top:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5)}.store-switcher .dropdown .dropdown-menu li{margin:0;padding:0}.store-switcher .dropdown .dropdown-menu li:hover{background:0 0;cursor:pointer}.store-switcher .dropdown.active{overflow:visible}.store-switcher .dropdown.active .dropdown-menu{display:block}.store-switcher .dropdown-menu{left:0;margin-top:.5em;max-height:250px;overflow-y:auto;padding-top:.25em}.store-switcher .dropdown-menu li{border:0;cursor:default}.store-switcher .dropdown-menu li:hover{cursor:default}.store-switcher .dropdown-menu li a,.store-switcher .dropdown-menu li span{color:#333;display:block;padding:.5rem 1.3rem}.store-switcher .dropdown-menu li a{text-decoration:none}.store-switcher .dropdown-menu li a:hover{background:#e9e9e9}.store-switcher .dropdown-menu li span{color:#adadad;cursor:default}.store-switcher .dropdown-menu li.current span{background:#eee;color:#333}.store-switcher .dropdown-menu .store-switcher-store a,.store-switcher .dropdown-menu .store-switcher-store span{padding-left:2.6rem}.store-switcher .dropdown-menu .store-switcher-store-view a,.store-switcher .dropdown-menu .store-switcher-store-view span{padding-left:3.9rem}.store-switcher .dropdown-menu .dropdown-toolbar{border-top:1px solid #ebebeb;margin-top:1rem}.store-switcher .dropdown-menu .dropdown-toolbar a:before{content:'\e610';margin-right:.25em;position:relative;top:1px}.store-switcher-label{font-weight:700}.store-switcher-alt{display:inline-block;position:relative}.store-switcher-alt.active .dropdown-menu{display:block}.store-switcher-alt .dropdown-menu{margin-top:2px;white-space:nowrap}.store-switcher-alt .dropdown-menu ul{list-style:none;margin:0;padding:0}.store-switcher-alt strong{color:#a79d95;display:block;font-size:14px;font-weight:500;line-height:1.333;padding:5px 10px}.store-switcher-alt .store-selected{color:#676056;cursor:pointer;font-size:12px;font-weight:400;line-height:1.333}.store-switcher-alt .store-selected:after{-webkit-font-smoothing:antialiased;color:#afadac;content:'\e02c';font-style:normal;font-weight:400;margin:0 0 0 3px;speak:none;vertical-align:text-top}.store-switcher-alt .store-switcher-store,.store-switcher-alt .store-switcher-website{padding:0}.store-switcher-alt .store-switcher-store:hover,.store-switcher-alt .store-switcher-website:hover{background:0 0}.store-switcher-alt .manage-stores,.store-switcher-alt .store-switcher-all,.store-switcher-alt .store-switcher-store-view{padding:0}.store-switcher-alt .manage-stores>a,.store-switcher-alt .store-switcher-all>a{color:#676056;display:block;font-size:12px;padding:8px 15px;text-decoration:none}.store-switcher-website{margin:5px 0 0}.store-switcher-website>strong{padding-left:13px}.store-switcher-store{margin:1px 0 0}.store-switcher-store>strong{padding-left:20px}.store-switcher-store>ul{margin-top:1px}.store-switcher-store-view:first-child{border-top:1px solid #e5e5e5}.store-switcher-store-view>a{color:#333;display:block;font-size:13px;padding:5px 15px 5px 24px;text-decoration:none}.store-view:not(.store-switcher){float:left}.store-view .store-switcher-label{display:inline-block;margin-top:1rem}.tooltip{margin-left:.5em}.tooltip .help a,.tooltip .help span{cursor:pointer;display:inline-block;height:22px;position:relative;vertical-align:middle;width:22px;z-index:2}.tooltip .help a:before,.tooltip .help span:before{color:#333;content:'\e633';font-size:1.7rem}.tooltip .help a:hover{text-decoration:none}.tooltip .tooltip-content{background:#000;border-radius:3px;color:#fff;display:none;margin-left:-19px;margin-top:10px;max-width:200px;padding:4px 8px;position:absolute;text-shadow:none;z-index:20}.tooltip .tooltip-content:before{border-bottom:5px solid #000;border-left:5px solid transparent;border-right:5px solid transparent;content:'';height:0;left:20px;opacity:.8;position:absolute;top:-5px;width:0}.tooltip .tooltip-content.loading{position:absolute}.tooltip .tooltip-content.loading:before{border-bottom-color:rgba(0,0,0,.3)}.tooltip:hover>.tooltip-content{display:block}.page-actions._fixed,.page-main-actions:not(._hidden){background:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;padding:1.5rem}.page-main-actions{margin:0 0 3rem}.page-main-actions._hidden .store-switcher{display:none}.page-main-actions._hidden .page-actions-placeholder{min-height:50px}.page-actions{float:right}.page-main-actions .page-actions._fixed{left:8.8rem;position:fixed;right:0;top:0;z-index:501}.page-main-actions .page-actions._fixed .page-actions-inner:before{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;content:attr(data-title);float:left;font-size:2.8rem;margin-top:.3rem;max-width:50%}.page-actions .page-actions-buttons>button,.page-actions>button{float:right;margin-left:1.3rem}.page-actions .page-actions-buttons>button.action-back,.page-actions .page-actions-buttons>button.back,.page-actions>button.action-back,.page-actions>button.back{float:left;-ms-flex-order:-1;order:-1}.page-actions .page-actions-buttons>button.action-back:before,.page-actions .page-actions-buttons>button.back:before,.page-actions>button.action-back:before,.page-actions>button.back:before{content:'\e626';margin-right:.5em;position:relative;top:1px}.page-actions .page-actions-buttons>button.action-primary,.page-actions .page-actions-buttons>button.primary,.page-actions>button.action-primary,.page-actions>button.primary{-ms-flex-order:2;order:2}.page-actions .page-actions-buttons>button.save:not(.primary),.page-actions>button.save:not(.primary){-ms-flex-order:1;order:1}.page-actions .page-actions-buttons>button.delete,.page-actions>button.delete{-ms-flex-order:-1;order:-1}.page-actions .actions-split{float:right;margin-left:1.3rem;-ms-flex-order:2;order:2}.page-actions .actions-split .dropdown-menu .item{display:block}.page-actions-buttons{float:right;-ms-flex-pack:end;justify-content:flex-end;display:-ms-flexbox;display:flex}.customer-index-edit .page-actions-buttons{background-color:transparent}.admin__page-nav{background:#f1f1f1;border:1px solid #e3e3e3}.admin__page-nav._collapsed:first-child{border-bottom:none}.admin__page-nav._collapsed._show{border-bottom:1px solid #e3e3e3}.admin__page-nav._collapsed._show ._collapsible{background:#f1f1f1}.admin__page-nav._collapsed._show ._collapsible:after{content:'\e62b'}.admin__page-nav._collapsed._show ._collapsible+.admin__page-nav-items{display:block}.admin__page-nav._collapsed._hide .admin__page-nav-title-messages,.admin__page-nav._collapsed._hide .admin__page-nav-title-messages ._active{display:inline-block}.admin__page-nav+._collapsed{border-bottom:none;border-top:none}.admin__page-nav-title{border-bottom:1px solid #e3e3e3;color:#303030;display:block;font-size:1.4rem;line-height:1.2;margin:0 0 -1px;padding:1.8rem 1.5rem;position:relative;text-transform:uppercase}.admin__page-nav-title._collapsible{background:#fff;cursor:pointer;margin:0;padding-right:3.5rem;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-title._collapsible+.admin__page-nav-items{display:none;margin-top:-1px}.admin__page-nav-title._collapsible:after{content:'\e628';font-size:1.3rem;font-weight:700;position:absolute;right:1.8rem;top:2rem}.admin__page-nav-title._collapsible:hover{background:#f1f1f1}.admin__page-nav-title._collapsible:last-child{margin:0 0 -1px}.admin__page-nav-title strong{font-weight:700}.admin__page-nav-title .admin__page-nav-title-messages{display:none}.admin__page-nav-items{list-style-type:none;margin:0;padding:1rem 0 1.3rem}.admin__page-nav-item{border-left:3px solid transparent;margin-left:.7rem;padding:0;position:relative;transition:border-color .1s ease-out,background-color .1s ease-out}.admin__page-nav-item:hover{border-color:#e4e4e4}.admin__page-nav-item:hover .admin__page-nav-link{background:#e4e4e4;color:#303030;text-decoration:none}.admin__page-nav-item._active,.admin__page-nav-item.ui-state-active{border-color:#eb5202}.admin__page-nav-item._active .admin__page-nav-link,.admin__page-nav-item.ui-state-active .admin__page-nav-link{background:#fff;border-color:#e3e3e3;border-right:1px solid #fff;color:#303030;margin-right:-1px;font-weight:600}.admin__page-nav-item._loading:before,.admin__page-nav-item.ui-tabs-loading:before{display:none}.admin__page-nav-item._loading .admin__page-nav-item-message-loader,.admin__page-nav-item.ui-tabs-loading .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-link{border:1px solid transparent;border-width:1px 0;color:#303030;display:block;font-weight:500;line-height:1.2;margin:0 0 -1px;padding:2rem 4rem 2rem 1rem;transition:border-color .1s ease-out,background-color .1s ease-out;word-wrap:break-word}.admin__page-nav-item-messages{display:inline-block}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-size:1.4rem;font-weight:400;left:-1rem;line-height:1.36;padding:1.5rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after,.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}.admin__page-nav-item-messages .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf;margin-top:1px}.admin__page-nav-item-message-loader{display:none;margin-top:-1rem;position:absolute;right:0;top:50%}.admin__page-nav-item-message-loader .spinner{font-size:2rem;margin-right:1.5rem}._loading>.admin__page-nav-item-messages .admin__page-nav-item-message-loader{display:inline-block}.admin__page-nav-item-message{position:relative}.admin__page-nav-item-message:hover{z-index:500}.admin__page-nav-item-message:hover .admin__page-nav-item-message-tooltip{display:block}.admin__page-nav-item-message._changed,.admin__page-nav-item-message._error{display:none}.admin__page-nav-item-message .admin__page-nav-item-message-icon{display:inline-block;font-size:1.4rem;padding-left:.8em;vertical-align:baseline}.admin__page-nav-item-message .admin__page-nav-item-message-icon:after{color:#666;content:'\e631'}._changed:not(._error)>.admin__page-nav-item-messages ._changed{display:inline-block}._error .admin__page-nav-item-message-icon:after{color:#eb5202;content:'\e623'}._error>.admin__page-nav-item-messages ._error{display:inline-block}._error>.admin__page-nav-item-messages ._error .spinner{font-size:2rem;margin-right:1.5rem}._error .admin__page-nav-item-message-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:3.7rem;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;left:-1rem;line-height:1.36;padding:2rem;position:absolute;text-transform:none;width:27rem;word-break:normal;z-index:2}._error .admin__page-nav-item-message-tooltip:after,._error .admin__page-nav-item-message-tooltip:before{border:15px solid transparent;height:0;width:0;border-top-color:#f1f1f1;content:'';display:block;left:2rem;position:absolute;top:100%;z-index:3}._error .admin__page-nav-item-message-tooltip:after{border-top-color:#f1f1f1;margin-top:-1px;z-index:4}._error .admin__page-nav-item-message-tooltip:before{border-top-color:#bfbfbf}.admin__data-grid-wrap-static .data-grid{box-sizing:border-box}.admin__data-grid-wrap-static .data-grid thead{color:#333}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td{background-color:#f5f5f5}.admin__data-grid-wrap-static .data-grid tr:nth-child(even) td._dragging{background-color:rgba(245,245,245,.95)}.admin__data-grid-wrap-static .data-grid ul{margin-left:1rem;padding-left:1rem}.admin__data-grid-wrap-static .admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-wrap-static .admin__data-grid-loading-mask .grid-loader{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-filters-actions-wrap{float:right}.data-grid-search-control-wrap{float:left;max-width:45.5rem;position:relative;width:35%}.data-grid-search-control-wrap :-ms-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-webkit-input-placeholder{font-style:italic}.data-grid-search-control-wrap ::-moz-placeholder{font-style:italic}.data-grid-search-control-wrap .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:.6rem 2rem .2rem;position:absolute;right:0;top:1px}.data-grid-search-control-wrap .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.data-grid-search-control-wrap .action-submit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.data-grid-search-control-wrap .action-submit:hover:before{color:#1a1a1a}._keyfocus .data-grid-search-control-wrap .action-submit:focus{box-shadow:0 0 0 1px #008bdb}.data-grid-search-control-wrap .action-submit:before{content:'\e60c';font-size:2rem;transition:color .1s linear}.data-grid-search-control-wrap .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.data-grid-search-control-wrap .abs-action-menu .action-submenu,.data-grid-search-control-wrap .abs-action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .action-menu,.data-grid-search-control-wrap .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu,.data-grid-search-control-wrap .actions-split .action-menu .action-submenu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu,.data-grid-search-control-wrap .actions-split .dropdown-menu .action-submenu .action-submenu{max-height:19.25rem;overflow-y:auto;z-index:398}.data-grid-search-control-wrap .action-menu-item._selected{background-color:#e0f6fe}.data-grid-search-control-wrap .data-grid-search-label{display:none}.data-grid-search-control{padding-right:6rem;width:100%}.data-grid-filters-action-wrap{float:left;padding-left:2rem}.data-grid-filters-action-wrap .action-default{font-size:1.3rem;margin-bottom:1rem;padding-left:1.7rem;padding-right:2.1rem;padding-top:.7rem}.data-grid-filters-action-wrap .action-default._active{background-color:#fff;border-bottom-color:#fff;border-right-color:#ccc;font-weight:600;margin:-.1rem 0 0;padding-bottom:1.6rem;padding-top:.8rem;position:relative;z-index:281}.data-grid-filters-action-wrap .action-default._active:after{background-color:#eb5202;bottom:100%;content:'';height:3px;left:-1px;position:absolute;right:-1px}.data-grid-filters-action-wrap .action-default:before{color:#333;content:'\e605';font-size:1.8rem;margin-right:.4rem;position:relative;top:-1px;vertical-align:top}.data-grid-filters-action-wrap .filters-active{display:none}.admin__action-grid-select .admin__control-select{margin:-.5rem .5rem 0 0;padding-bottom:.6rem;padding-top:.6rem}.admin__data-grid-filters-wrap{opacity:0;visibility:hidden;clear:both;font-size:1.3rem;transition:opacity .3s ease}.admin__data-grid-filters-wrap._show{opacity:1;visibility:visible;border-bottom:1px solid #ccc;border-top:1px solid #ccc;margin-bottom:.7rem;padding:3.6rem 0 3rem;position:relative;top:-1px;z-index:280}.admin__data-grid-filters-wrap._show .admin__data-grid-filters,.admin__data-grid-filters-wrap._show .admin__data-grid-filters-footer{display:block}.admin__data-grid-filters-wrap .admin__form-field-label,.admin__data-grid-filters-wrap .admin__form-field-legend{display:block;font-weight:700;margin:0 0 .3rem;text-align:left}.admin__data-grid-filters-wrap .admin__form-field{display:inline-block;margin-bottom:2em;margin-left:0;padding-left:2rem;padding-right:2rem;vertical-align:top;width:calc(100% / 4 - 4px)}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field{display:block;float:none;margin-bottom:1.5rem;padding-left:0;padding-right:0;width:auto}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field:last-child{margin-bottom:0}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-label{border:1px solid transparent;float:left;font-weight:400;line-height:1.36;margin-bottom:0;padding-bottom:.6rem;padding-right:1em;padding-top:.6rem;width:25%}.admin__data-grid-filters-wrap .admin__form-field .admin__form-field .admin__form-field-control{margin-left:25%}.admin__data-grid-filters-wrap .admin__action-multiselect,.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text,.admin__data-grid-filters-wrap .admin__form-field-label{font-size:1.3rem}.admin__data-grid-filters-wrap .admin__control-select{height:3.2rem;padding-top:.5rem}.admin__data-grid-filters-wrap .admin__action-multiselect:before{height:3.2rem;width:3.2rem}.admin__data-grid-filters-wrap .admin__control-select,.admin__data-grid-filters-wrap .admin__control-text._has-datepicker{width:100%}.admin__data-grid-filters{display:none;margin-left:-2rem;margin-right:-2rem}.admin__filters-legend{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-filters-footer{display:none;font-size:1.4rem}.admin__data-grid-filters-footer .admin__footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-filters-footer .admin__footer-secondary-actions{float:left;width:50%}.admin__data-grid-filters-current{border-bottom:.1rem solid #ccc;border-top:.1rem solid #ccc;display:none;font-size:1.3rem;margin-bottom:.9rem;padding-bottom:.8rem;padding-top:1.1rem;width:100%}.admin__data-grid-filters-current._show{display:table;position:relative;top:-1px;z-index:3}.admin__data-grid-filters-current._show+.admin__data-grid-filters-wrap._show{margin-top:-1rem}.admin__current-filters-actions-wrap,.admin__current-filters-list-wrap,.admin__current-filters-title-wrap{display:table-cell;vertical-align:top}.admin__current-filters-title{margin-right:1em;white-space:nowrap}.admin__current-filters-list-wrap{width:100%}.admin__current-filters-list{margin-bottom:0}.admin__current-filters-list>li{display:inline-block;font-weight:600;margin:0 1rem .5rem;padding-right:2.6rem;position:relative}.admin__current-filters-list .action-remove{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;padding:0;line-height:1;position:absolute;right:0;top:1px}.admin__current-filters-list .action-remove:hover{background-color:transparent;border:none;box-shadow:none}.admin__current-filters-list .action-remove:hover:before{color:#949494}.admin__current-filters-list .action-remove:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__current-filters-list .action-remove:before{color:#adadad;content:'\e620';font-size:1.6rem;transition:color .1s linear}.admin__current-filters-list .action-remove>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__current-filters-actions-wrap .action-clear{border:none;padding-bottom:0;padding-top:0;white-space:nowrap}.admin__data-grid-pager-wrap{float:right;text-align:right}.admin__data-grid-pager{display:inline-block;margin-left:3rem}.admin__data-grid-pager .admin__control-text::-webkit-inner-spin-button,.admin__data-grid-pager .admin__control-text::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.admin__data-grid-pager .admin__control-text{-moz-appearance:textfield;text-align:center;width:4.4rem}.action-next,.action-previous{width:4.4rem}.action-next:before,.action-previous:before{font-weight:700}.action-next>span,.action-previous>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.action-previous{margin-right:2.5rem;text-indent:-.25em}.action-previous:before{content:'\e629'}.action-next{margin-left:1.5rem;text-indent:.1em}.action-next:before{content:'\e62a'}.admin__data-grid-action-bookmarks{opacity:.98}.admin__data-grid-action-bookmarks .admin__action-dropdown-text:after{left:0;right:-6px}.admin__data-grid-action-bookmarks._active{z-index:290}.admin__data-grid-action-bookmarks .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:15rem;min-width:4.9rem;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown:before{content:'\e60f'}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu{font-size:1.3rem;left:0;padding:1rem 0;right:auto}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li{padding:0 5rem 0 0;position:relative;white-space:nowrap}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action){transition:background-color .1s linear}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu>li:not(.action-dropdown-menu-action):hover{background-color:#e3e3e3}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item{max-width:23rem;min-width:18rem;white-space:normal;word-break:break-all}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit{display:none;padding-bottom:1rem;padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-edit .action-dropdown-menu-item-actions{padding-bottom:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action{padding-left:1rem;padding-top:1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action+.action-dropdown-menu-item-last{padding-top:.5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a{color:#008bdb;text-decoration:none;display:inline-block;padding-left:1.1rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-action>a:hover{color:#0fa7ff;text-decoration:underline}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-last{padding-bottom:0}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item{display:none}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._edit .action-dropdown-menu-item-edit{display:block}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu ._active .action-dropdown-menu-link{font-weight:600}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{font-size:1.3rem;min-width:15rem;width:calc(100% - 4rem)}.ie9 .admin__data-grid-action-bookmarks .admin__action-dropdown-menu .admin__control-text{width:15rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-item-actions{border-left:1px solid #fff;bottom:0;position:absolute;right:0;top:0;width:5rem}.admin__data-grid-action-bookmarks .admin__action-dropdown-menu .action-dropdown-menu-link{color:#333;display:block;text-decoration:none;padding:1rem 1rem 1rem 2.1rem}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit,.admin__data-grid-action-bookmarks .action-submit{background-color:transparent;border:none;border-radius:0;box-shadow:none;margin:0;vertical-align:top}.admin__data-grid-action-bookmarks .action-delete:hover,.admin__data-grid-action-bookmarks .action-edit:hover,.admin__data-grid-action-bookmarks .action-submit:hover{background-color:transparent;border:none;box-shadow:none}.admin__data-grid-action-bookmarks .action-delete:before,.admin__data-grid-action-bookmarks .action-edit:before,.admin__data-grid-action-bookmarks .action-submit:before{font-size:1.7rem}.admin__data-grid-action-bookmarks .action-delete>span,.admin__data-grid-action-bookmarks .action-edit>span,.admin__data-grid-action-bookmarks .action-submit>span{clip:rect(0,0,0,0);overflow:hidden;position:absolute}.admin__data-grid-action-bookmarks .action-delete,.admin__data-grid-action-bookmarks .action-edit{padding:.6rem 1.4rem}.admin__data-grid-action-bookmarks .action-delete:active,.admin__data-grid-action-bookmarks .action-edit:active{-ms-transform:scale(0.9);transform:scale(0.9)}.admin__data-grid-action-bookmarks .action-submit{padding:.6rem 1rem .6rem .8rem}.admin__data-grid-action-bookmarks .action-submit:active{position:relative;right:-1px}.admin__data-grid-action-bookmarks .action-submit:before{content:'\e625'}.admin__data-grid-action-bookmarks .action-delete:before{content:'\e630'}.admin__data-grid-action-bookmarks .action-edit{padding-top:.8rem}.admin__data-grid-action-bookmarks .action-edit:before{content:'\e631'}.admin__data-grid-action-columns._active{opacity:.98;z-index:290}.admin__data-grid-action-columns .admin__action-dropdown:before{content:'\e610';font-size:1.8rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-columns-menu{color:#303030;font-size:1.3rem;overflow:hidden;padding:2.2rem 3.5rem 1rem;z-index:1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-header{border-bottom:1px solid #d1d1d1}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-content{width:49.2rem}.admin__data-grid-action-columns-menu._overflow .admin__action-dropdown-menu-footer{border-top:1px solid #d1d1d1;padding-top:2.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-content{max-height:22.85rem;overflow-y:auto;padding-top:1.5rem;position:relative;width:47.4rem}.admin__data-grid-action-columns-menu .admin__field-option{float:left;height:1.9rem;margin-bottom:1.5rem;padding:0 1rem 0 0;width:15.8rem}.admin__data-grid-action-columns-menu .admin__field-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-header{padding-bottom:1.5rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-menu-footer{padding:1rem 0 2rem}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-main-actions{margin-left:25%;text-align:right}.admin__data-grid-action-columns-menu .admin__action-dropdown-footer-secondary-actions{float:left;margin-left:-1em}.admin__data-grid-action-export._active{opacity:.98;z-index:290}.admin__data-grid-action-export .admin__action-dropdown:before{content:'\e635';font-size:1.7rem;left:.3rem;margin-right:.7rem;vertical-align:top}.admin__data-grid-action-export-menu{padding-left:2rem;padding-right:2rem;padding-top:1rem}.admin__data-grid-action-export-menu .admin__action-dropdown-footer-main-actions{padding-bottom:2rem;padding-top:2.5rem;white-space:nowrap}.sticky-header{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:8.8rem;margin-top:-1px;padding:.5rem 3rem 0;position:fixed;right:0;top:77px;z-index:398}.sticky-header .admin__data-grid-wrap{margin-bottom:0;overflow-x:visible;padding-bottom:0}.sticky-header .admin__data-grid-header-row{position:relative;text-align:right}.sticky-header .admin__data-grid-header-row:last-child{margin:0}.sticky-header .admin__data-grid-actions-wrap,.sticky-header .admin__data-grid-filters-wrap,.sticky-header .admin__data-grid-pager-wrap,.sticky-header .data-grid-filters-actions-wrap,.sticky-header .data-grid-search-control-wrap{display:inline-block;float:none;vertical-align:top}.sticky-header .action-select-wrap{float:left;margin-right:1.5rem;width:16.66666667%}.sticky-header .admin__control-support-text{float:left}.sticky-header .data-grid-search-control-wrap{margin:-.5rem 0 0 1.1rem;width:auto}.sticky-header .data-grid-search-control-wrap .data-grid-search-label{box-sizing:border-box;cursor:pointer;display:block;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;position:relative;text-align:center}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:before{color:#333;content:'\e60c';font-size:2rem;transition:color .1s linear}.sticky-header .data-grid-search-control-wrap .data-grid-search-label:hover:before{color:#000}.sticky-header .data-grid-search-control-wrap .data-grid-search-label span{display:none}.sticky-header .data-grid-filters-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-left:0;position:relative}.sticky-header .data-grid-filters-actions-wrap .action-default{background-color:transparent;border:1px solid transparent;box-sizing:border-box;min-width:3.8rem;padding:1.2rem .6rem 1.7rem;text-align:center;transition:all .15s ease}.sticky-header .data-grid-filters-actions-wrap .action-default span{display:none}.sticky-header .data-grid-filters-actions-wrap .action-default:before{margin:0}.sticky-header .data-grid-filters-actions-wrap .action-default._active{background-color:#fff;border-color:#adadad #adadad #fff;box-shadow:1px 1px 5px rgba(0,0,0,.5);z-index:210}.sticky-header .data-grid-filters-actions-wrap .action-default._active:after{background-color:#fff;content:'';height:6px;left:-2px;position:absolute;right:-6px;top:100%}.sticky-header .data-grid-filters-action-wrap{padding:0}.sticky-header .admin__data-grid-filters-wrap{background-color:#fff;border:1px solid #adadad;box-shadow:0 5px 5px 0 rgba(0,0,0,.25);left:0;padding-left:3.5rem;padding-right:3.5rem;position:absolute;top:100%;width:100%;z-index:209}.sticky-header .admin__data-grid-filters-current+.admin__data-grid-filters-wrap._show{margin-top:-6px}.sticky-header .filters-active{background-color:#e04f00;border-radius:10px;color:#fff;display:block;font-size:1.4rem;font-weight:700;padding:.1rem .7rem;position:absolute;right:-7px;top:0;z-index:211}.sticky-header .filters-active:empty{padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-actions-wrap{margin:-.5rem 0 0 1.1rem;padding-right:.3rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown{background-color:transparent;box-sizing:border-box;min-width:3.8rem;padding-left:.6rem;padding-right:.6rem;text-align:center}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown .admin__action-dropdown-text{display:inline-block;max-width:0;min-width:0;overflow:hidden}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:before{margin:0}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap{margin-right:1.1rem}.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after,.sticky-header .admin__data-grid-actions-wrap .admin__action-dropdown:after{display:none}.sticky-header .admin__data-grid-actions-wrap ._active .admin__action-dropdown{background-color:#fff}.sticky-header .admin__data-grid-action-bookmarks .admin__action-dropdown:before{position:relative;top:-3px}.sticky-header .admin__data-grid-filters-current{border-bottom:0;border-top:0;margin-bottom:0;padding-bottom:0;padding-top:0}.sticky-header .admin__data-grid-pager .admin__control-text,.sticky-header .admin__data-grid-pager-wrap .admin__control-support-text,.sticky-header .data-grid-search-control-wrap .action-submit,.sticky-header .data-grid-search-control-wrap .data-grid-search-control{display:none}.sticky-header .action-next{margin:0}.sticky-header .data-grid{margin-bottom:-1px}.data-grid-cap-left,.data-grid-cap-right{background-color:#f8f8f8;bottom:-2px;position:absolute;top:6rem;width:3rem;z-index:201}.data-grid-cap-left{left:0}.admin__data-grid-header{font-size:1.4rem}.admin__data-grid-header-row+.admin__data-grid-header-row{margin-top:1.1rem}.admin__data-grid-header-row:last-child{margin-bottom:0}.admin__data-grid-header-row .action-select-wrap{display:block}.admin__data-grid-header-row .action-select{width:100%}.admin__data-grid-actions-wrap{float:right;margin-left:1.1rem;margin-top:-.5rem;text-align:right}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap{position:relative;text-align:left;vertical-align:middle}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._hide+.admin__action-dropdown-wrap:after,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:first-child:after{display:none}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown,.admin__data-grid-actions-wrap .admin__action-dropdown-wrap._active .admin__action-dropdown-menu{border-color:#adadad}.admin__data-grid-actions-wrap .admin__action-dropdown-wrap:after{border-left:1px solid #ccc;content:'';height:3.2rem;left:0;position:absolute;top:.5rem;z-index:3}.admin__data-grid-actions-wrap .admin__action-dropdown{padding-bottom:1.7rem;padding-top:1.2rem}.admin__data-grid-actions-wrap .admin__action-dropdown:after{margin-top:-.4rem}.admin__data-grid-outer-wrap{min-height:8rem;position:relative}.admin__data-grid-wrap{margin-bottom:2rem;max-width:100%;overflow-x:auto;padding-bottom:1rem;padding-top:2rem}.admin__data-grid-loading-mask{background:rgba(255,255,255,.5);bottom:0;left:0;position:absolute;right:0;top:0;z-index:399}.admin__data-grid-loading-mask .spinner{font-size:4rem;left:50%;margin-left:-2rem;margin-top:-2rem;position:absolute;top:50%}.ie9 .admin__data-grid-loading-mask .spinner{background:url(../images/loader-2.gif) 50% 50% no-repeat;bottom:0;height:149px;left:0;margin:auto;position:absolute;right:0;top:0;width:218px}.data-grid-cell-content{display:inline-block;overflow:hidden;width:100%}body._in-resize{cursor:col-resize;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body._in-resize *,body._in-resize .data-grid-th,body._in-resize .data-grid-th._draggable,body._in-resize .data-grid-th._sortable{cursor:col-resize!important}._layout-fixed{table-layout:fixed}.data-grid{border:none;font-size:1.3rem;margin-bottom:0;width:100%}.data-grid:not(._dragging-copy) ._odd-row td._dragging{background-color:#d0d0d0}.data-grid:not(._dragging-copy) ._dragging{background-color:#d9d9d9;color:rgba(48,48,48,.95)}.data-grid:not(._dragging-copy) ._dragging a{color:rgba(0,139,219,.95)}.data-grid:not(._dragging-copy) ._dragging a:hover{color:rgba(15,167,255,.95)}.data-grid._dragged{outline:#007bdb solid 1px}.data-grid thead{background-color:transparent}.data-grid tfoot th{padding:1rem}.data-grid tr._odd-row td{background-color:#f5f5f5}.data-grid tr._odd-row td._update-status-active{background:#89e1ff}.data-grid tr._odd-row td._update-status-upcoming{background:#b7ee63}.data-grid tr:hover td._update-status-active,.data-grid tr:hover td._update-status-upcoming{background-color:#e5f7fe}.data-grid tr.data-grid-tr-no-data td{font-size:1.6rem;padding:3rem;text-align:center}.data-grid tr.data-grid-tr-no-data:hover td{background-color:#fff;cursor:default}.data-grid tr:active td{background-color:#e0f6fe}.data-grid tr:hover td{background-color:#e5f7fe}.data-grid tr._dragged td{background:#d0d0d0}.data-grid tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.data-grid tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.data-grid tr:not(.data-grid-editable-row):last-child td{border-bottom:.1rem solid #d6d6d6}.data-grid tr ._clickable,.data-grid tr._clickable{cursor:pointer}.data-grid tr._disabled{pointer-events:none}.data-grid td,.data-grid th{font-size:1.3rem;line-height:1.36;transition:background-color .1s linear;vertical-align:top}.data-grid td._resizing,.data-grid th._resizing{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid td._hidden,.data-grid th._hidden{display:none}.data-grid td._fit,.data-grid th._fit{width:1%}.data-grid td{background-color:#fff;border-left:.1rem dashed #d6d6d6;border-right:.1rem dashed #d6d6d6;color:#303030;padding:1rem}.data-grid td:first-child{border-left-style:solid}.data-grid td:last-child{border-right-style:solid}.data-grid td .action-select-wrap{position:static}.data-grid td .action-select{color:#008bdb;text-decoration:none;background-color:transparent;border:none;font-size:1.3rem;padding:0 3rem 0 0;position:relative}.data-grid td .action-select:hover{color:#0fa7ff;text-decoration:underline}.data-grid td .action-select:hover:after{border-color:#0fa7ff transparent transparent}.data-grid td .action-select:after{border-color:#008bdb transparent transparent;margin:.6rem 0 0 .7rem;right:auto;top:auto}.data-grid td .action-select:before{display:none}.data-grid td .abs-action-menu .action-submenu,.data-grid td .abs-action-menu .action-submenu .action-submenu,.data-grid td .action-menu,.data-grid td .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu,.data-grid td .actions-split .action-menu .action-submenu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu,.data-grid td .actions-split .dropdown-menu .action-submenu .action-submenu{left:auto;min-width:10rem;right:0;text-align:left;top:auto;z-index:1}.data-grid td._update-status-active{background:#bceeff}.data-grid td._update-status-upcoming{background:#ccf391}.data-grid th{background-color:#514943;border:.1rem solid #8a837f;border-left-color:transparent;color:#fff;font-weight:600;padding:0;text-align:left}.data-grid th:first-child{border-left-color:#8a837f}.data-grid th._dragover-left{box-shadow:inset 3px 0 0 0 #fff;z-index:2}.data-grid th._dragover-right{box-shadow:inset -3px 0 0 0 #fff}.data-grid .shadow-div{cursor:col-resize;height:100%;margin-right:-5px;position:absolute;right:0;top:0;width:10px}.data-grid .data-grid-th{background-clip:padding-box;color:#fff;padding:1rem;position:relative;vertical-align:middle}.data-grid .data-grid-th._resize-visible .shadow-div{cursor:auto;display:none}.data-grid .data-grid-th._draggable{cursor:grab}.data-grid .data-grid-th._sortable{cursor:pointer;transition:background-color .1s linear;z-index:1}.data-grid .data-grid-th._sortable:focus,.data-grid .data-grid-th._sortable:hover{background-color:#5f564f}.data-grid .data-grid-th._sortable:active{padding-bottom:.9rem;padding-top:1.1rem}.data-grid .data-grid-th.required>span:after{color:#f38a5e;content:'*';margin-left:.3rem}.data-grid .data-grid-checkbox-cell{overflow:hidden;padding:0;vertical-align:top;width:5.2rem}.data-grid .data-grid-checkbox-cell:hover{cursor:default}.data-grid .data-grid-thumbnail-cell{text-align:center;width:7rem}.data-grid .data-grid-thumbnail-cell img{border:1px solid #d6d6d6;width:5rem}.data-grid .data-grid-multicheck-cell{padding:1rem 1rem .9rem;text-align:center;vertical-align:middle}.data-grid .data-grid-onoff-cell{text-align:center;width:12rem}.data-grid .data-grid-actions-cell{padding-left:2rem;padding-right:2rem;text-align:center;width:1%}.data-grid._hidden{display:none}.data-grid._dragging-copy{box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;opacity:.95;position:fixed;top:0;z-index:1000}.data-grid._dragging-copy .data-grid-th{border:1px solid #007bdb;border-bottom:none}.data-grid._dragging-copy .data-grid-th,.data-grid._dragging-copy .data-grid-th._sortable{cursor:grabbing}.data-grid._dragging-copy tr:last-child td{border-bottom:1px solid #007bdb}.data-grid._dragging-copy td{border-left:1px solid #007bdb;border-right:1px solid #007bdb}.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid._dragging-copy._in-edit .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:rgba(255,251,230,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td,.data-grid._dragging-copy._in-edit .data-grid-editable-row:hover td{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:after,.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{left:0;right:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:before{background-color:rgba(255,255,255,.95)}.data-grid._dragging-copy._in-edit .data-grid-editable-row td:only-child{border-left:1px solid #007bdb;border-right:1px solid #007bdb;left:0}.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-select,.data-grid._dragging-copy._in-edit .data-grid-editable-row .admin__control-text{opacity:.5}.data-grid .data-grid-controls-row td{padding-top:1.6rem}.data-grid .data-grid-controls-row td.data-grid-checkbox-cell{padding-top:.6rem}.data-grid .data-grid-controls-row td [class*=admin__control-],.data-grid .data-grid-controls-row td button{margin-top:-1.7rem}.data-grid._in-edit tr:hover td{background-color:#e6e6e6}.data-grid._in-edit ._odd-row.data-grid-editable-row td,.data-grid._in-edit ._odd-row.data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit ._odd-row td,.data-grid._in-edit ._odd-row:hover td{background-color:#dcdcdc}.data-grid._in-edit .data-grid-editable-row-actions td,.data-grid._in-edit .data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid._in-edit td{background-color:#e6e6e6;pointer-events:none}.data-grid._in-edit .data-grid-checkbox-cell{pointer-events:auto}.data-grid._in-edit .data-grid-editable-row{border:.1rem solid #adadad;border-bottom-color:#c2c2c2}.data-grid._in-edit .data-grid-editable-row:hover td{background-color:#fff}.data-grid._in-edit .data-grid-editable-row td{background-color:#fff;border-bottom-color:#fff;border-left-style:hidden;border-right-style:hidden;border-top-color:#fff;pointer-events:auto;vertical-align:middle}.data-grid._in-edit .data-grid-editable-row td:first-child{border-left-color:#adadad;border-left-style:solid}.data-grid._in-edit .data-grid-editable-row td:first-child:after,.data-grid._in-edit .data-grid-editable-row td:first-child:before{left:0}.data-grid._in-edit .data-grid-editable-row td:last-child{border-right-color:#adadad;border-right-style:solid;left:-.1rem}.data-grid._in-edit .data-grid-editable-row td:last-child:after,.data-grid._in-edit .data-grid-editable-row td:last-child:before{right:0}.data-grid._in-edit .data-grid-editable-row .admin__control-select,.data-grid._in-edit .data-grid-editable-row .admin__control-text{width:100%}.data-grid._in-edit .data-grid-bulk-edit-panel td{vertical-align:bottom}.data-grid .data-grid-editable-row td{border-left-color:#fff;border-left-style:solid;position:relative;z-index:1}.data-grid .data-grid-editable-row td:after{bottom:0;box-shadow:0 5px 5px rgba(0,0,0,.25);content:'';height:.9rem;left:0;margin-top:-1rem;position:absolute;right:0}.data-grid .data-grid-editable-row td:before{background-color:#fff;bottom:0;content:'';height:1rem;left:-10px;position:absolute;right:-10px;z-index:1}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td,.data-grid .data-grid-editable-row.data-grid-editable-row-actions:hover td{background-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:first-child{border-left-color:#fff;border-right-color:#fff}.data-grid .data-grid-editable-row.data-grid-editable-row-actions td:last-child{left:0}.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel td:before,.data-grid .data-grid-editable-row.data-grid-bulk-edit-panel:hover td{background-color:#fffbe6}.data-grid .data-grid-editable-row-actions{left:50%;margin-left:-12.5rem;margin-top:-2px;position:absolute;text-align:center}.data-grid .data-grid-editable-row-actions td{width:25rem}.data-grid .data-grid-editable-row-actions [class*=action-]{min-width:9rem}.data-grid .data-grid-draggable-row-cell{width:1%}.data-grid .data-grid-draggable-row-cell .draggable-handle{padding:0}.data-grid-th._sortable._ascend,.data-grid-th._sortable._descend{padding-right:2.7rem}.data-grid-th._sortable._ascend:before,.data-grid-th._sortable._descend:before{margin-top:-1em;position:absolute;right:1rem;top:50%}.data-grid-th._sortable._ascend:before{content:'\2193'}.data-grid-th._sortable._descend:before{content:'\2191'}.data-grid-checkbox-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:right}.data-grid-checkbox-cell-inner:hover{cursor:pointer}.data-grid-state-cell-inner{display:block;padding:1.1rem 1.8rem .9rem;text-align:center}.data-grid-state-cell-inner>span{display:inline-block;font-style:italic;padding:.6rem 0}.data-grid-row-parent._active>td .data-grid-checkbox-cell-inner:before{content:'\e62b'}.data-grid-row-parent>td .data-grid-checkbox-cell-inner{padding-left:3.7rem;position:relative}.data-grid-row-parent>td .data-grid-checkbox-cell-inner:before{content:'\e628';font-size:1rem;font-weight:700;left:1.35rem;position:absolute;top:1.6rem}.data-grid-th._col-xs{width:1%}.data-grid-info-panel{box-shadow:0 0 5px rgba(0,0,0,.5);margin:2rem .1rem -2rem}.data-grid-info-panel .messages{overflow:hidden}.data-grid-info-panel .messages .message{margin:1rem}.data-grid-info-panel .messages .message:last-child{margin-bottom:1rem}.data-grid-info-panel-actions{padding:1rem;text-align:right}.data-grid-editable-row .admin__field-control{position:relative}.data-grid-editable-row .admin__field-control._error:after{border-color:transparent #ee7d7d transparent transparent;border-style:solid;border-width:0 12px 12px 0;content:'';position:absolute;right:0;top:0}.data-grid-editable-row .admin__field-control._error .admin__control-text{border-color:#ee7d7d}.data-grid-editable-row .admin__field-control._focus:after{display:none}.data-grid-editable-row .admin__field-error{bottom:100%;box-shadow:1px 1px 5px rgba(0,0,0,.5);left:0;margin:0 auto 1.5rem;max-width:32rem;position:absolute;right:0}.data-grid-editable-row .admin__field-error:after,.data-grid-editable-row .admin__field-error:before{border-style:solid;content:'';left:50%;position:absolute;top:100%}.data-grid-editable-row .admin__field-error:after{border-color:#fffbbb transparent transparent;border-width:10px 10px 0;margin-left:-10px;z-index:1}.data-grid-editable-row .admin__field-error:before{border-color:#ee7d7d transparent transparent;border-width:11px 12px 0;margin-left:-12px}.data-grid-bulk-edit-panel .admin__field-label-vertical{display:block;font-size:1.2rem;margin-bottom:.5rem;text-align:left}.data-grid-row-changed{cursor:default;display:block;opacity:.5;position:relative;width:100%;z-index:1}.data-grid-row-changed:after{content:'\e631';display:inline-block}.data-grid-row-changed .data-grid-row-changed-tooltip{background:#f1f1f1;border:1px solid #f1f1f1;border-radius:1px;bottom:100%;box-shadow:0 3px 9px 0 rgba(0,0,0,.3);display:none;font-weight:400;line-height:1.36;margin-bottom:1.5rem;padding:1rem;position:absolute;right:-1rem;text-transform:none;width:27rem;word-break:normal;z-index:2}.data-grid-row-changed._changed{opacity:1;z-index:3}.data-grid-row-changed._changed:hover .data-grid-row-changed-tooltip{display:block}.data-grid-row-changed._changed:hover:before{background:#f1f1f1;border:1px solid #f1f1f1;bottom:100%;box-shadow:4px 4px 3px -1px rgba(0,0,0,.15);content:'';display:block;height:1.6rem;left:50%;margin:0 0 .7rem -.8rem;position:absolute;-ms-transform:rotate(45deg);transform:rotate(45deg);width:1.6rem;z-index:3}.ie9 .data-grid-row-changed._changed:hover:before{display:none}.admin__data-grid-outer-wrap .data-grid-checkbox-cell{overflow:hidden}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner{position:relative}.admin__data-grid-outer-wrap .data-grid-checkbox-cell-inner:before{bottom:0;content:'';height:500%;left:0;position:absolute;right:0;top:0}.admin__data-grid-wrap-static .data-grid-checkbox-cell:hover{cursor:pointer}.admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:1.1rem 1.8rem .9rem;padding:0}.adminhtml-cms-hierarchy-index .admin__data-grid-wrap-static .data-grid-actions-cell:first-child{padding:0}.adminhtml-export-index .admin__data-grid-wrap-static .data-grid-checkbox-cell-inner{margin:0;padding:1.1rem 1.8rem 1.9rem}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before,.admin__control-file-label:before,.admin__control-multiselect,.admin__control-select,.admin__control-text,.admin__control-textarea,.selectmenu{-webkit-appearance:none;background-color:#fff;border:1px solid #adadad;border-radius:1px;box-shadow:none;color:#303030;font-size:1.4rem;font-weight:400;height:auto;line-height:1.36;padding:.6rem 1rem;transition:border-color .1s linear;vertical-align:baseline;width:auto}.admin__control-addon [class*=admin__control-][class]:hover~[class*=admin__addon-]:last-child:before,.admin__control-multiselect:hover,.admin__control-select:hover,.admin__control-text:hover,.admin__control-textarea:hover,.selectmenu:hover,.selectmenu:hover .selectmenu-toggle:before{border-color:#878787}.admin__control-addon [class*=admin__control-][class]:focus~[class*=admin__addon-]:last-child:before,.admin__control-file:active+.admin__control-file-label:before,.admin__control-file:focus+.admin__control-file-label:before,.admin__control-multiselect:focus,.admin__control-select:focus,.admin__control-text:focus,.admin__control-textarea:focus,.selectmenu._focus,.selectmenu._focus .selectmenu-toggle:before{border-color:#007bdb;box-shadow:none;outline:0}.admin__control-addon [class*=admin__control-][class][disabled]~[class*=admin__addon-]:last-child:before,.admin__control-file[disabled]+.admin__control-file-label:before,.admin__control-multiselect[disabled],.admin__control-select[disabled],.admin__control-text[disabled],.admin__control-textarea[disabled]{background-color:#e9e9e9;border-color:#adadad;color:#303030;cursor:not-allowed;opacity:.5}.admin__field-row[class]>.admin__field-control,.admin__fieldset>.admin__field.admin__field-wide[class]>.admin__field-control{clear:left;float:none;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label{display:block;line-height:1.4rem;margin-bottom:.86rem;margin-top:-.14rem;text-align:left;width:auto}.admin__field-row[class]:not(.admin__field-option)>.admin__field-label:before,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)>.admin__field-label:before{display:none}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span{padding-left:1.5rem}.admin__field-row[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__field-row[class]:not(.admin__field-option).required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option)._required>.admin__field-label span:after,.admin__fieldset>.admin__field.admin__field-wide[class]:not(.admin__field-option).required>.admin__field-label span:after{left:0;margin-left:30px}.admin__legend{font-size:1.8rem;font-weight:600;margin-bottom:3rem}.admin__control-checkbox,.admin__control-radio{cursor:pointer;opacity:.01;overflow:hidden;position:absolute;vertical-align:top}.admin__control-checkbox:after,.admin__control-radio:after{display:none}.admin__control-checkbox+label,.admin__control-radio+label{cursor:pointer;display:inline-block}.admin__control-checkbox+label:before,.admin__control-radio+label:before{background-color:#fff;border:1px solid #adadad;color:transparent;float:left;height:1.6rem;text-align:center;vertical-align:top;width:1.6rem}.admin__control-checkbox+.admin__field-label,.admin__control-radio+.admin__field-label{padding-left:2.6rem}.admin__control-checkbox+.admin__field-label:before,.admin__control-radio+.admin__field-label:before{margin:1px 1rem 0 -2.6rem}.admin__control-checkbox:checked+label:before,.admin__control-radio:checked+label:before{color:#514943}.admin__control-checkbox.disabled+label,.admin__control-checkbox[disabled]+label,.admin__control-radio.disabled+label,.admin__control-radio[disabled]+label{color:#303030;cursor:default;opacity:.5}.admin__control-checkbox.disabled+label:before,.admin__control-checkbox[disabled]+label:before,.admin__control-radio.disabled+label:before,.admin__control-radio[disabled]+label:before{background-color:#e9e9e9;border-color:#adadad;cursor:default}._keyfocus .admin__control-checkbox:not(.disabled):focus+label:before,._keyfocus .admin__control-checkbox:not([disabled]):focus+label:before,._keyfocus .admin__control-radio:not(.disabled):focus+label:before,._keyfocus .admin__control-radio:not([disabled]):focus+label:before{border-color:#007bdb}.admin__control-checkbox:not(.disabled):hover+label:before,.admin__control-checkbox:not([disabled]):hover+label:before,.admin__control-radio:not(.disabled):hover+label:before,.admin__control-radio:not([disabled]):hover+label:before{border-color:#878787}.admin__control-radio+label:before{border-radius:1.6rem;content:'';transition:border-color .1s linear,color .1s ease-in}.admin__control-radio.admin__control-radio+label:before{line-height:140%}.admin__control-radio:checked+label{position:relative}.admin__control-radio:checked+label:after{background-color:#514943;border-radius:50%;content:'';height:10px;left:3px;position:absolute;top:4px;width:10px}.admin__control-radio:checked:not(.disabled):hover,.admin__control-radio:checked:not(.disabled):hover+label,.admin__control-radio:checked:not([disabled]):hover,.admin__control-radio:checked:not([disabled]):hover+label{cursor:default}.admin__control-radio:checked:not(.disabled):hover+label:before,.admin__control-radio:checked:not([disabled]):hover+label:before{border-color:#adadad}.admin__control-checkbox+label:before{border-radius:1px;content:'';font-size:0;transition:font-size .1s ease-out,color .1s ease-out,border-color .1s linear}.admin__control-checkbox:checked+label:before{content:'\e62d';font-size:1.1rem;line-height:125%}.admin__control-checkbox:not(:checked)._indeterminate+label:before,.admin__control-checkbox:not(:checked):indeterminate+label:before{color:#514943;content:'-';font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:700}input[type=checkbox].admin__control-checkbox,input[type=radio].admin__control-checkbox{margin:0;position:absolute}.admin__control-text{min-width:4rem}.admin__control-select{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#adadad,#adadad);background-position:calc(100% - 12px) -34px,100%,calc(100% - 3.2rem) 0;background-size:auto,3.2rem 100%,1px 100%;background-repeat:no-repeat;max-width:100%;min-width:8.5rem;padding-bottom:.5rem;padding-right:4.4rem;padding-top:.5rem;transition:border-color .1s linear}.admin__control-select:hover{border-color:#878787;cursor:pointer}.admin__control-select:focus{background-image:url(../images/arrows-bg.svg),linear-gradient(#e3e3e3,#e3e3e3),linear-gradient(#007bdb,#007bdb);background-position:calc(100% - 12px) 13px,100%,calc(100% - 3.2rem) 0;border-color:#007bdb}.admin__control-select::-ms-expand{display:none}.ie9 .admin__control-select{background-image:none;padding-right:1rem}option:empty{display:none}.admin__control-multiselect{height:auto;max-width:100%;min-width:15rem;overflow:auto;padding:0;resize:both}.admin__control-multiselect optgroup,.admin__control-multiselect option{padding:.5rem 1rem}.admin__control-file-wrapper{display:inline-block;padding:.5rem 1rem;position:relative;z-index:1}.admin__control-file-label:before{content:'';left:0;position:absolute;top:0;width:100%;z-index:0}.admin__control-file{background:0 0;border:0;padding-top:.7rem;position:relative;width:auto;z-index:1}.admin__control-support-text{border:1px solid transparent;display:inline-block;font-size:1.4rem;line-height:1.36;padding-bottom:.6rem;padding-top:.6rem}.admin__control-support-text+[class*=admin__control-],[class*=admin__control-]+.admin__control-support-text{margin-left:.7rem}.admin__control-service{float:left;margin:.8rem 0 0 3rem}.admin__control-textarea{height:8.48rem;line-height:1.18;padding-top:.8rem;resize:vertical}.admin__control-addon{-ms-flex-direction:row;flex-direction:row;display:inline-flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;position:relative;width:100%;z-index:1}.admin__control-addon>[class*=admin__addon-],.admin__control-addon>[class*=admin__control-]{-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:1}.admin__control-addon .admin__control-select{width:auto}.admin__control-addon .admin__control-text{margin:.1rem;padding:.5rem .9rem;width:100%}.admin__control-addon [class*=admin__control-][class]{appearence:none;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-order:1;order:1;-ms-flex-negative:1;flex-shrink:1;background-color:transparent;border-color:transparent;box-shadow:none;vertical-align:top}.admin__control-addon [class*=admin__control-][class]+[class*=admin__control-]{border-left-color:#adadad}.admin__control-addon [class*=admin__control-][class] :focus{box-shadow:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child{padding-left:1rem;position:static!important;z-index:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child>*{position:relative;vertical-align:top;z-index:1}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:empty{padding:0}.admin__control-addon [class*=admin__control-][class]~[class*=admin__addon-]:last-child:before{bottom:0;box-sizing:border-box;content:'';left:0;position:absolute;top:0;width:100%;z-index:-1}.admin__addon-prefix,.admin__addon-suffix{border:0;box-sizing:border-box;color:#858585;display:inline-block;font-size:1.4rem;font-weight:400;height:3.2rem;line-height:3.2rem;padding:0}.admin__addon-suffix{-ms-flex-order:3;order:3}.admin__addon-suffix:last-child{padding-right:1rem}.admin__addon-prefix{-ms-flex-order:0;order:0}.ie9 .admin__control-addon:after{clear:both;content:'';display:block;height:0;overflow:hidden}.ie9 .admin__addon{min-width:0;overflow:hidden;text-align:right;white-space:nowrap;width:auto}.ie9 .admin__addon [class*=admin__control-]{display:inline}.ie9 .admin__addon-prefix{float:left}.ie9 .admin__addon-suffix{float:right}.admin__control-collapsible{width:100%}.admin__control-collapsible ._dragged .admin__collapsible-block-wrapper .admin__collapsible-title{background:#d0d0d0}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before,.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{background:#008bdb;content:'';display:block;height:3px;left:0;position:absolute;right:0}.admin__control-collapsible ._dragover-top .admin__collapsible-block-wrapper:before{top:-3px}.admin__control-collapsible ._dragover-bottom .admin__collapsible-block-wrapper:before{bottom:-3px}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper{border:0;margin:0;position:relative}.admin__control-collapsible .admin__collapsible-block-wrapper.fieldset-wrapper .fieldset-wrapper-title{background:#f8f8f8;border:2px solid #ccc}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title{font-size:1.4rem;font-weight:400;line-height:1;padding:1.6rem 4rem 1.6rem 3.8rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .admin__collapsible-title:before{left:1rem;right:auto;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding:0;position:absolute;right:1rem;top:1.4rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete:before{content:'\e630';font-size:2rem}.admin__control-collapsible .admin__collapsible-block-wrapper .fieldset-wrapper-title .action-delete>span{display:none}.admin__control-collapsible .admin__collapsible-content{background-color:#fff;margin-bottom:1rem}.admin__control-collapsible .admin__collapsible-content>.fieldset-wrapper{border:1px solid #ccc;margin-top:-1px;padding:1rem}.admin__control-collapsible .admin__collapsible-content .admin__fieldset{padding:0}.admin__control-collapsible .admin__collapsible-content .admin__field:last-child{margin-bottom:0}.admin__control-table-wrapper{max-width:100%;overflow-x:auto;overflow-y:hidden}.admin__control-table{width:100%}.admin__control-table thead{background-color:transparent}.admin__control-table tbody td{vertical-align:top}.admin__control-table tfoot th{padding-bottom:1.3rem}.admin__control-table tfoot th.validation{padding-bottom:0;padding-top:0}.admin__control-table tfoot td{border-top:1px solid #fff}.admin__control-table tfoot .admin__control-table-pagination{float:right;padding-bottom:0}.admin__control-table tfoot .action-previous{margin-right:.5rem}.admin__control-table tfoot .action-next{margin-left:.9rem}.admin__control-table tr:last-child td{border-bottom:none}.admin__control-table tr._dragover-top td{box-shadow:inset 0 3px 0 0 #008bdb}.admin__control-table tr._dragover-bottom td{box-shadow:inset 0 -3px 0 0 #008bdb}.admin__control-table tr._dragged td,.admin__control-table tr._dragged th{background:#d0d0d0}.admin__control-table td,.admin__control-table th{background-color:#efefef;border:0;border-bottom:1px solid #fff;padding:1.3rem 1rem 1.3rem 0;text-align:left;vertical-align:top}.admin__control-table td:first-child,.admin__control-table th:first-child{padding-left:1rem}.admin__control-table td>.admin__control-select,.admin__control-table td>.admin__control-text,.admin__control-table th>.admin__control-select,.admin__control-table th>.admin__control-text{width:100%}.admin__control-table td._hidden,.admin__control-table th._hidden{display:none}.admin__control-table td._fit,.admin__control-table th._fit{width:1px}.admin__control-table th{color:#303030;font-size:1.4rem;font-weight:600;vertical-align:bottom}.admin__control-table th._required span:after{color:#eb5202;content:'*'}.admin__control-table .control-table-actions-th{white-space:nowrap}.admin__control-table .control-table-actions-cell{padding-top:1.8rem;text-align:center;width:1%}.admin__control-table .control-table-options-th{text-align:center;width:10rem}.admin__control-table .control-table-options-cell{text-align:center}.admin__control-table .control-table-text{line-height:3.2rem}.admin__control-table .col-draggable{padding-top:2.2rem;width:1%}.admin__control-table .action-delete{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.admin__control-table .action-delete:hover{background-color:transparent;border-color:transparent;box-shadow:none}.admin__control-table .action-delete:before{content:'\e630';font-size:2rem}.admin__control-table .action-delete>span{display:none}.admin__control-table .draggable-handle{padding:0}.admin__control-table._dragged{outline:#007bdb solid 1px}.admin__control-table-action{background-color:#efefef;border-top:1px solid #fff;padding:1.3rem 1rem}.admin__dynamic-rows._dragged{opacity:.95;position:absolute;z-index:999}.admin__dynamic-rows.admin__control-table .admin__control-fields>.admin__field{border:0;padding:0}.admin__dynamic-rows td>.admin__field{border:0;margin:0;padding:0}.admin__control-table-pagination{padding-bottom:1rem}.admin__control-table-pagination .admin__data-grid-pager{float:right}.admin__field-tooltip{display:inline-block;margin-top:.5rem;max-width:45px;overflow:visible;vertical-align:top;width:0}.admin__field-tooltip:hover{position:relative;z-index:500}.admin__field-option .admin__field-tooltip{margin-top:.5rem}.admin__field-tooltip .admin__field-tooltip-action{margin-left:2rem;position:relative;z-index:2;display:inline-block;text-decoration:none}.admin__field-tooltip .admin__field-tooltip-action:before{-webkit-font-smoothing:antialiased;font-size:2.2rem;line-height:1;color:#514943;content:'\e633';font-family:Icons;vertical-align:middle;display:inline-block;font-weight:400;overflow:hidden;speak:none;text-align:center}.admin__field-tooltip .admin__control-text:focus+.admin__field-tooltip-content,.admin__field-tooltip:hover .admin__field-tooltip-content{display:block}.admin__field-tooltip .admin__field-tooltip-content{bottom:3.8rem;display:none;right:-2.3rem}.admin__field-tooltip .admin__field-tooltip-content:after,.admin__field-tooltip .admin__field-tooltip-content:before{border:1.6rem solid transparent;height:0;width:0;border-top-color:#afadac;content:'';display:block;position:absolute;right:2rem;top:100%;z-index:3}.admin__field-tooltip .admin__field-tooltip-content:after{border-top-color:#fffbbb;margin-top:-1px;z-index:4}.abs-admin__field-tooltip-content,.admin__field-tooltip .admin__field-tooltip-content{box-shadow:0 2px 8px 0 rgba(0,0,0,.3);background:#fffbbb;border:1px solid #afadac;border-radius:1px;padding:1.5rem 2.5rem;position:absolute;width:32rem;z-index:1}.admin__field-fallback-reset{font-size:1.25rem;white-space:nowrap;width:30px}.admin__field-fallback-reset>span{margin-left:.5rem;position:relative}.admin__field-fallback-reset:active{-ms-transform:scale(0.98);transform:scale(0.98)}.admin__field-fallback-reset:before{transition:color .1s linear;content:'\e642';font-size:1.3rem;margin-left:.5rem}.admin__field-fallback-reset:hover{cursor:pointer;text-decoration:none}.admin__field-fallback-reset:focus{background:0 0}.abs-field-size-x-small,.abs-field-sizes.admin__field-x-small>.admin__field-control,.admin__field.admin__field-x-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-x-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-x-small>.admin__field-control{width:8rem}.abs-field-size-small,.abs-field-sizes.admin__field-small>.admin__field-control,.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control,.admin__field.admin__field-small>.admin__field-control,.admin__fieldset>.admin__field.admin__field-small>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-small>.admin__field-control{width:15rem}.abs-field-size-medium,.abs-field-sizes.admin__field-medium>.admin__field-control,.admin__field.admin__field-medium>.admin__field-control,.admin__fieldset>.admin__field.admin__field-medium>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-medium>.admin__field-control{width:34rem}.abs-field-size-large,.abs-field-sizes.admin__field-large>.admin__field-control,.admin__field.admin__field-large>.admin__field-control,.admin__fieldset>.admin__field.admin__field-large>.admin__field-control,[class*=admin__control-grouped]>.admin__field.admin__field-large>.admin__field-control{width:64rem}.abs-field-no-label,.admin__field-group-additional,.admin__field-no-label,.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-control{margin-left:calc((100%) * .25 + 30px)}.admin__fieldset{border:0;margin:0;min-width:0;padding:0}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title{padding-left:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section>.fieldset-wrapper-title strong{font-size:1.7rem;font-weight:600}.admin__fieldset .fieldset-wrapper.admin__fieldset-section .admin__fieldset-wrapper-content>.admin__fieldset{padding-top:1rem}.admin__fieldset .fieldset-wrapper.admin__fieldset-section:last-child .admin__fieldset-wrapper-content>.admin__fieldset{padding-bottom:0}.admin__fieldset>.admin__field{border:0;margin:0 0 0 -30px;padding:0}.admin__fieldset>.admin__field:after{clear:both;content:'';display:table}.admin__fieldset>.admin__field>.admin__field-control{width:calc((100%) * .5 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.admin__fieldset>.admin__field.admin__field-no-label>.admin__field-label{display:none}.admin__fieldset>.admin__field+.admin__field._empty._no-header{margin-top:-3rem}.admin__fieldset-product-websites{position:relative;z-index:300}.admin__fieldset-note{margin-bottom:2rem}.admin__form-field{border:0;margin:0;padding:0}.admin__field-control .admin__control-text,.admin__field-control .admin__control-textarea,.admin__form-field-control .admin__control-text,.admin__form-field-control .admin__control-textarea{width:100%}.admin__field-label{color:#303030;cursor:pointer;margin:0;text-align:right}.admin__field-label+br{display:none}.admin__field:not(.admin__field-option)>.admin__field-label{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.4rem;font-weight:600;line-height:3.2rem;padding:0;white-space:nowrap}.admin__field:not(.admin__field-option)>.admin__field-label:before{opacity:0;visibility:hidden;content:'.';margin-left:-7px;overflow:hidden}.admin__field:not(.admin__field-option)>.admin__field-label span{display:inline-block;line-height:1.2;vertical-align:middle;white-space:normal}.admin__field:not(.admin__field-option)>.admin__field-label span[data-config-scope]{position:relative}._required>.admin__field-label>span:after,.required>.admin__field-label>span:after{color:#eb5202;content:'*';display:inline-block;font-size:1.6rem;font-weight:500;line-height:1;margin-left:10px;margin-top:.2rem;position:absolute;z-index:1}._disabled>.admin__field-label{color:#999;cursor:default}.admin__field{margin-bottom:0}.admin__field+.admin__field{margin-top:1.5rem}.admin__field:not(.admin__field-option)~.admin__field-option{margin-top:.5rem}.admin__field.admin__field-option~.admin__field-option{margin-top:.9rem}.admin__field~.admin__field-option:last-child{margin-bottom:.8rem}.admin__fieldset>.admin__field{margin-bottom:3rem;position:relative}.admin__field legend.admin__field-label{opacity:0}.admin__field[data-config-scope]:before{color:gray;content:attr(data-config-scope);display:inline-block;font-size:1.2rem;left:calc((100%) * .75 - 30px);line-height:3.2rem;margin-left:60px;position:absolute;width:calc((100%) * .25 - 30px)}.admin__field-control .admin__field[data-config-scope]:nth-child(n+2):before{content:''}.admin__field._error .admin__field-control [class*=admin__addon-]:before,.admin__field._error .admin__field-control [class*=admin__control-] [class*=admin__addon-]:before,.admin__field._error .admin__field-control>[class*=admin__control-]{border-color:#e22626}.admin__field._disabled,.admin__field._disabled:hover{box-shadow:inherit;cursor:inherit;opacity:1;outline:inherit}.admin__field._hidden{display:none}.admin__field-control+.admin__field-control{margin-top:1.5rem}.admin__field-control._with-tooltip>.admin__control-addon,.admin__field-control._with-tooltip>.admin__control-select,.admin__field-control._with-tooltip>.admin__control-text,.admin__field-control._with-tooltip>.admin__control-textarea,.admin__field-control._with-tooltip>.admin__field-option{max-width:calc(100% - 45px - 4px)}.admin__field-control._with-tooltip .admin__field-tooltip{width:auto}.admin__field-control._with-tooltip .admin__field-option{display:inline-block}.admin__field-control._with-reset>.admin__control-addon,.admin__field-control._with-reset>.admin__control-text,.admin__field-control._with-reset>.admin__control-textarea{width:calc(100% - 30px - .5rem - 4px)}.admin__field-control._with-reset .admin__field-fallback-reset{margin-left:.5rem;margin-top:1rem;vertical-align:top}.admin__field-control._with-reset._with-tooltip>.admin__control-addon,.admin__field-control._with-reset._with-tooltip>.admin__control-text,.admin__field-control._with-reset._with-tooltip>.admin__control-textarea{width:calc(100% - 30px - .5rem - 45px - 8px)}.admin__fieldset>.admin__field-collapsible{margin-bottom:0}.admin__fieldset>.admin__field-collapsible .admin__field-control{border-top:1px solid #ccc;display:block;font-size:1.7rem;font-weight:700;padding:1.7rem 0;width:calc(97%)}.admin__fieldset>.admin__field-collapsible .admin__field-option{padding-top:0}.admin__field-collapsible+div{margin-top:2.5rem}.admin__field-collapsible .admin__control-radio+label:before{height:1.8rem;width:1.8rem}.admin__field-collapsible .admin__control-radio:checked+label:after{left:4px;top:5px}.admin__field-error{background:#fffbbb;border:1px solid #ee7d7d;box-sizing:border-box;color:#555;display:block;font-size:1.2rem;font-weight:400;line-height:1.2;margin:.2rem 0 0;padding:.8rem 1rem .9rem}.admin__field-note{color:#303030;font-size:1.2rem;margin:10px 0 0;padding:0}.admin__additional-info{padding-top:1rem}.admin__field-option{padding-top:.7rem}.admin__field-option .admin__field-label{text-align:left}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2),.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1){display:inline-block}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option{display:inline-block;margin-left:41px;margin-top:0}.admin__field-control>.admin__field-option:nth-child(1):nth-last-child(2)+.admin__field-option:before,.admin__field-control>.admin__field-option:nth-child(2):nth-last-child(1)+.admin__field-option:before{background:#cacaca;content:'';display:inline-block;height:20px;margin-left:-20px;position:absolute;width:1px}.admin__field-value{display:inline-block;padding-top:.7rem}.admin__field-service{padding-top:1rem}.admin__control-fields>.admin__field:first-child,[class*=admin__control-grouped]>.admin__field:first-child{position:static}.admin__control-fields>.admin__field:first-child>.admin__field-label,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label{width:calc((100%) * .25 - 30px);float:left;margin-left:30px;background:#fff;cursor:pointer;left:0;position:absolute;top:0}.admin__control-fields>.admin__field:first-child>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field:first-child>.admin__field-label span:before{display:block}.admin__control-fields>.admin__field._disabled>.admin__field-label,[class*=admin__control-grouped]>.admin__field._disabled>.admin__field-label{cursor:default}.admin__control-fields>.admin__field>.admin__field-label span:before,[class*=admin__control-grouped]>.admin__field>.admin__field-label span:before{display:none}.admin__control-fields .admin__field-label~.admin__field-control{width:100%}.admin__control-fields .admin__field-option{padding-top:0}[class*=admin__control-grouped]{box-sizing:border-box;display:table;width:100%}[class*=admin__control-grouped]>.admin__field{display:table-cell;vertical-align:top}[class*=admin__control-grouped]>.admin__field>.admin__field-control{float:none;width:100%}[class*=admin__control-grouped]>.admin__field.admin__field-default,[class*=admin__control-grouped]>.admin__field.admin__field-large,[class*=admin__control-grouped]>.admin__field.admin__field-medium,[class*=admin__control-grouped]>.admin__field.admin__field-small,[class*=admin__control-grouped]>.admin__field.admin__field-x-small{width:1px}[class*=admin__control-grouped]>.admin__field.admin__field-default+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-large+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-medium+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-small+.admin__field:last-child,[class*=admin__control-grouped]>.admin__field.admin__field-x-small+.admin__field:last-child{width:auto}[class*=admin__control-grouped]>.admin__field:nth-child(n+2){padding-left:20px}.admin__control-group-equal{table-layout:fixed}.admin__control-group-equal>.admin__field{width:50%}.admin__field-control-group{margin-top:.8rem}.admin__field-control-group>.admin__field{padding:0}.admin__control-grouped-date>.admin__field-date{white-space:nowrap;width:1px}.admin__control-grouped-date>.admin__field-date.admin__field>.admin__field-control{float:left;position:relative}.admin__control-grouped-date>.admin__field-date+.admin__field:last-child{width:auto}.admin__control-grouped-date>.admin__field-date+.admin__field-date>.admin__field-label{float:left;padding-right:20px}.admin__control-grouped-date .ui-datepicker-trigger{left:100%;top:0}.admin__field-group-columns.admin__field-control.admin__control-grouped{width:calc((100%) * 1 - 30px);float:left;margin-left:30px}.admin__field-group-columns>.admin__field:first-child>.admin__field-label{float:none;margin:0;opacity:1;position:static;text-align:left}.admin__field-group-columns .admin__control-select{width:100%}.admin__field-group-additional{clear:both}.admin__field-group-additional .action-advanced{margin-top:1rem}.admin__field-group-additional .action-secondary{width:100%}.admin__field-group-show-label{white-space:nowrap}.admin__field-group-show-label>.admin__field-control,.admin__field-group-show-label>.admin__field-label{display:inline-block;vertical-align:top}.admin__field-group-show-label>.admin__field-label{margin-right:20px}.admin__field-complex{margin:1rem 0 3rem;padding-left:1rem}.admin__field:not(._hidden)+.admin__field-complex{margin-top:3rem}.admin__field-complex .admin__field-complex-title{clear:both;color:#303030;font-size:1.7rem;font-weight:600;letter-spacing:.025em;margin-bottom:1rem}.admin__field-complex .admin__field-complex-elements{float:right;max-width:40%}.admin__field-complex .admin__field-complex-elements button{margin-left:1rem}.admin__field-complex .admin__field-complex-content{max-width:60%;overflow:hidden}.admin__field-complex .admin__field-complex-text{margin-left:-1rem}.admin__field-complex+.admin__field._empty._no-header{margin-top:-3rem}.admin__legend{float:left;position:static;width:100%}.admin__legend+br{clear:left;display:block;height:0;overflow:hidden}.message{margin-bottom:3rem}.message-icon-top:before{margin-top:0;top:1.8rem}.nav{background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;border-top:1px solid #e3e3e3;display:none;margin-bottom:3rem;padding:2.2rem 1.5rem 0 0}.nav .btn-group,.nav-bar-outer-actions{float:right;margin-bottom:1.7rem}.nav .btn-group .btn-wrap,.nav-bar-outer-actions .btn-wrap{float:right;margin-left:.5rem;margin-right:.5rem}.nav .btn-group .btn-wrap .btn,.nav-bar-outer-actions .btn-wrap .btn{padding-left:.5rem;padding-right:.5rem}.nav-bar-outer-actions{margin-top:-10.6rem;padding-right:1.5rem}.btn-wrap-try-again{width:9.5rem}.btn-wrap-next,.btn-wrap-prev{width:8.5rem}.nav-bar{counter-reset:i;float:left;margin:0 1rem 1.7rem 0;padding:0;position:relative;white-space:nowrap}.nav-bar:before{background-color:#d4d4d4;background-repeat:repeat-x;background-image:linear-gradient(to bottom,#d1d1d1 0,#d4d4d4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d1d1d1', endColorstr='#d4d4d4', GradientType=0);border-bottom:1px solid #d9d9d9;border-top:1px solid #bfbfbf;content:'';height:1rem;left:5.15rem;position:absolute;right:5.15rem;top:.7rem}.nav-bar>li{display:inline-block;font-size:0;position:relative;vertical-align:top;width:10.3rem}.nav-bar>li:first-child:after{display:none}.nav-bar>li:after{background-color:#514943;content:'';height:.5rem;left:calc(-50% + .25rem);position:absolute;right:calc(50% + .7rem);top:.9rem}.nav-bar>li.disabled:before,.nav-bar>li.ui-state-disabled:before{bottom:0;content:'';left:0;position:absolute;right:0;top:0;z-index:1}.nav-bar>li.active~li:after,.nav-bar>li.ui-state-active~li:after{display:none}.nav-bar>li.active~li a:after,.nav-bar>li.ui-state-active~li a:after{background-color:transparent;border-color:transparent;color:#a6a6a6}.nav-bar>li.active a,.nav-bar>li.ui-state-active a{color:#000}.nav-bar>li.active a:hover,.nav-bar>li.ui-state-active a:hover{cursor:default}.nav-bar>li.active a:after,.nav-bar>li.ui-state-active a:after{background-color:#fff;content:''}.nav-bar a{color:#514943;display:block;font-size:1.2rem;font-weight:600;line-height:1.2;overflow:hidden;padding:3rem .5em 0;position:relative;text-align:center;text-overflow:ellipsis}.nav-bar a:hover{text-decoration:none}.nav-bar a:after{background-color:#514943;border:.4rem solid #514943;border-radius:100%;color:#fff;content:counter(i);counter-increment:i;height:1.5rem;left:50%;line-height:.6;margin-left:-.8rem;position:absolute;right:auto;text-align:center;top:.4rem;width:1.5rem}.nav-bar a:before{background-color:#d6d6d6;border:1px solid transparent;border-bottom-color:#d9d9d9;border-radius:100%;border-top-color:#bfbfbf;content:'';height:2.3rem;left:50%;line-height:1;margin-left:-1.2rem;position:absolute;top:0;width:2.3rem}.tooltip{display:block;font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:1.19rem;font-weight:400;line-height:1.4;opacity:0;position:absolute;visibility:visible;z-index:10}.tooltip.in{opacity:.9}.tooltip.top{margin-top:-4px;padding:8px 0}.tooltip.right{margin-left:4px;padding:0 8px}.tooltip.bottom{margin-top:4px;padding:8px 0}.tooltip.left{margin-left:-4px;padding:0 8px}.tooltip p:last-child{margin-bottom:0}.tooltip-inner{background-color:#fff;border:1px solid #adadad;border-radius:0;box-shadow:1px 1px 1px #ccc;color:#41362f;max-width:31rem;padding:.5em 1em;text-decoration:none}.tooltip-arrow,.tooltip-arrow:after{border:solid transparent;height:0;position:absolute;width:0}.tooltip-arrow:after{content:'';position:absolute}.tooltip.top .tooltip-arrow,.tooltip.top .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:50%;margin-left:-8px}.tooltip.top-left .tooltip-arrow,.tooltip.top-left .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;margin-bottom:-8px;right:8px}.tooltip.top-right .tooltip-arrow,.tooltip.top-right .tooltip-arrow:after{border-top-color:#949494;border-width:8px 8px 0;bottom:0;left:8px;margin-bottom:-8px}.tooltip.right .tooltip-arrow,.tooltip.right .tooltip-arrow:after{border-right-color:#949494;border-width:8px 8px 8px 0;left:1px;margin-top:-8px;top:50%}.tooltip.right .tooltip-arrow:after{border-right-color:#fff;border-width:6px 7px 6px 0;margin-left:0;margin-top:-6px}.tooltip.left .tooltip-arrow,.tooltip.left .tooltip-arrow:after{border-left-color:#949494;border-width:8px 0 8px 8px;margin-top:-8px;right:0;top:50%}.tooltip.bottom .tooltip-arrow,.tooltip.bottom .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:50%;margin-left:-8px;top:0}.tooltip.bottom-left .tooltip-arrow,.tooltip.bottom-left .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;margin-top:-8px;right:8px;top:0}.tooltip.bottom-right .tooltip-arrow,.tooltip.bottom-right .tooltip-arrow:after{border-bottom-color:#949494;border-width:0 8px 8px;left:8px;margin-top:-8px;top:0}.password-strength{display:block;margin:0 -.3rem 1em;white-space:nowrap}.password-strength.password-strength-too-short .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child,.password-strength.password-strength-weak .password-strength-item:first-child+.password-strength-item{background-color:#e22626}.password-strength.password-strength-fair .password-strength-item:first-child,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-fair .password-strength-item:first-child+.password-strength-item+.password-strength-item{background-color:#ef672f}.password-strength.password-strength-good .password-strength-item:first-child,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item,.password-strength.password-strength-good .password-strength-item:first-child+.password-strength-item+.password-strength-item+.password-strength-item,.password-strength.password-strength-strong .password-strength-item{background-color:#79a22e}.password-strength .password-strength-item{background-color:#ccc;display:inline-block;font-size:0;height:1.4rem;margin-right:.3rem;width:calc(20% - .6rem)}@keyframes progress-bar-stripes{from{background-position:4rem 0}to{background-position:0 0}}.progress{background-color:#fafafa;border:1px solid #ccc;clear:left;height:3rem;margin-bottom:3rem;overflow:hidden}.progress-bar{background-color:#79a22e;color:#fff;float:left;font-size:1.19rem;height:100%;line-height:3rem;text-align:center;transition:width .6s ease;width:0}.progress-bar.active{animation:progress-bar-stripes 2s linear infinite}.progress-bar-text-description{margin-bottom:1.6rem}.progress-bar-text-progress{text-align:right}.page-columns .page-inner-sidebar{margin:0 0 3rem}.page-header{margin-bottom:2.7rem;padding-bottom:2rem;position:relative}.page-header:before{border-bottom:1px solid #e3e3e3;bottom:0;content:'';display:block;height:1px;left:3rem;position:absolute;right:3rem}.container .page-header:before{content:normal}.page-header .message{margin-bottom:1.8rem}.page-header .message+.message{margin-top:-1.5rem}.page-header .admin__action-dropdown,.page-header .search-global-input{transition:none}.container .page-header{margin-bottom:0}.page-title-wrapper{margin-top:1.1rem}.container .page-title-wrapper{background:url(../../pub/images/logo.svg) no-repeat;min-height:41px;padding:4px 0 0 45px}.admin__menu .level-0:first-child>a{margin-top:1.6rem}.admin__menu .level-0:first-child>a:after{top:-1.6rem}.admin__menu .level-0:first-child._active>a:after{display:block}.admin__menu .level-0>a{padding-bottom:1.3rem;padding-top:1.3rem}.admin__menu .level-0>a:before{margin-bottom:.7rem}.admin__menu .item-home>a:before{content:'\e611';font-size:2.3rem;padding-top:-.1rem}.admin__menu .item-component>a:before{content:'\e612'}.admin__menu .item-extension>a:before{content:'\e647'}.admin__menu .item-upgrade>a:before{content:'\e614'}.admin__menu .item-system-config>a:before{content:'\e610'}.admin__menu .item-tools>a:before{content:'\e613'}.modal-sub-title{font-size:1.7rem;font-weight:600}.modal-connect-signin .modal-inner-wrap{max-width:80rem}@keyframes ngdialog-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes ngdialog-fadein{0%{opacity:0}100%{opacity:1}}.ngdialog{-webkit-overflow-scrolling:touch;bottom:0;box-sizing:border-box;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:999}.ngdialog *,.ngdialog:after,.ngdialog:before{box-sizing:inherit}.ngdialog.ngdialog-disabled-animation *{animation:none!important}.ngdialog.ngdialog-closing .ngdialog-content,.ngdialog.ngdialog-closing .ngdialog-overlay{-webkit-animation:ngdialog-fadeout .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadeout .5s}.ngdialog-overlay{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s;background:rgba(0,0,0,.4);bottom:0;left:0;position:fixed;right:0;top:0}.ngdialog-content{-webkit-animation:ngdialog-fadein .5s;-webkit-backface-visibility:hidden;animation:ngdialog-fadein .5s}body.ngdialog-open{overflow:hidden}.component-indicator{border-radius:50%;cursor:help;display:inline-block;height:16px;text-align:center;vertical-align:middle;width:16px}.component-indicator::after,.component-indicator::before{background:#fff;display:block;opacity:0;position:absolute;transition:opacity .2s linear .1s;visibility:hidden}.component-indicator::before{border:1px solid #adadad;border-radius:1px;box-shadow:0 0 2px rgba(0,0,0,.4);content:attr(data-label);font-size:1.2rem;margin:30px 0 0 -10px;min-width:50px;padding:4px 5px}.component-indicator::after{border-color:#999;border-style:solid;border-width:1px 0 0 1px;box-shadow:-1px -1px 1px rgba(0,0,0,.1);content:'';height:10px;margin:9px 0 0 5px;-ms-transform:rotate(45deg);transform:rotate(45deg);width:10px}.component-indicator:hover::after,.component-indicator:hover::before{opacity:1;transition:opacity .2s linear;visibility:visible}.component-indicator span{display:block;height:16px;overflow:hidden;width:16px}.component-indicator span:before{content:'';display:block;font-family:Icons;font-size:16px;height:100%;line-height:16px;width:100%}.component-indicator._on{background:#79a22e}.component-indicator._off{background:#e22626}.component-indicator._off span:before{background:#fff;height:4px;margin:8px auto 20px;width:12px}.component-indicator._info{background:0 0}.component-indicator._info span{width:21px}.component-indicator._info span:before{color:#008bdb;content:'\e648';font-family:Icons;font-size:16px}.component-indicator._tooltip{background:0 0;margin:0 0 8px 5px}.component-indicator._tooltip a{width:21px}.component-indicator._tooltip a:hover{text-decoration:none}.component-indicator._tooltip a:before{color:#514943;content:'\e633';font-family:Icons;font-size:16px}.col-manager-item-name .data-grid-data{padding-left:5px}.col-manager-item-name .ng-hide+.data-grid-data{padding-left:24px}.col-manager-item-name ._hide-dependencies,.col-manager-item-name ._show-dependencies{cursor:pointer;padding-left:24px;position:relative}.col-manager-item-name ._hide-dependencies:before,.col-manager-item-name ._show-dependencies:before{display:block;font-family:Icons;font-size:12px;left:0;position:absolute;top:1px}.col-manager-item-name ._show-dependencies:before{content:'\e62b'}.col-manager-item-name ._hide-dependencies:before{content:'\e628'}.col-manager-item-name ._no-dependencies{padding-left:24px}.product-modules-block{font-size:1.2rem;padding:15px 0 0}.col-manager-item-name .product-modules-block{padding-left:1rem}.product-modules-descriprion,.product-modules-title{font-weight:700;margin:0 0 7px}.product-modules-list{font-size:1.1rem;list-style:none;margin:0}.col-manager-item-name .product-modules-list{margin-left:15px}.col-manager-item-name .product-modules-list li{padding:0 0 0 15px;position:relative}.product-modules-list li{margin:0 0 .5rem}.product-modules-list .component-indicator{height:10px;left:0;position:absolute;top:3px;width:10px}.module-summary{white-space:nowrap}.module-summary-title{font-size:2.1rem;margin-right:1rem}.app-updater .nav{display:block;margin-bottom:3.1rem;margin-top:-2.8rem}.app-updater .nav-bar-outer-actions{margin-top:1rem;padding-right:0}.app-updater .nav-bar-outer-actions .btn-wrap-cancel{margin-right:2.6rem}.main{padding-bottom:2rem;padding-top:3rem}.menu-wrapper .logo-static{pointer-events:none}.header{display:none}.header .logo{float:left;height:4.1rem;width:3.5rem}.header-title{font-size:2.8rem;letter-spacing:.02em;line-height:1.4;margin:2.5rem 0 3.5rem 5rem}.page-title{margin-bottom:1rem}.page-sub-title{font-size:2rem}.accent-box{margin-bottom:2rem}.accent-box .btn-prime{margin-top:1.5rem}.spinner.side{float:left;font-size:2.4rem;margin-left:2rem;margin-top:-5px}.page-landing{margin:7.6% auto 0;max-width:44rem;text-align:center}.page-landing .logo{height:5.6rem;margin-bottom:2rem;width:19.2rem}.page-landing .text-version{margin-bottom:3rem}.page-landing .text-welcome{margin-bottom:6.5rem}.page-landing .text-terms{margin-bottom:2.5rem;text-align:center}.page-landing .btn-submit,.page-license .license-text{margin-bottom:2rem}.page-license .page-license-footer{text-align:right}.readiness-check-item{margin-bottom:4rem;min-height:2.5rem}.readiness-check-item .spinner{float:left;font-size:2.5rem;margin:-.4rem 0 0 1.7rem}.readiness-check-title{font-size:1.4rem;font-weight:700;margin-bottom:.1rem;margin-left:5.7rem}.readiness-check-content{margin-left:5.7rem;margin-right:22rem;position:relative}.readiness-check-content .readiness-check-title{margin-left:0}.readiness-check-content .list{margin-top:-.3rem}.readiness-check-side{left:100%;padding-left:2.4rem;position:absolute;top:0;width:22rem}.readiness-check-side .side-title{margin-bottom:0}.readiness-check-icon{float:left;margin-left:1.7rem;margin-top:.3rem}.extensions-information{margin-bottom:5rem}.extensions-information h3{font-size:1.4rem;margin-bottom:1.3rem}.extensions-information .message{margin-bottom:2.5rem}.extensions-information .message:before{margin-top:0;top:1.8rem}.extensions-information .extensions-container{padding:0 2rem}.extensions-information .list{margin-bottom:1rem}.extensions-information .list select{cursor:pointer}.extensions-information .list select:disabled{background:#ccc;cursor:default}.extensions-information .list .extension-delete{font-size:1.7rem;padding-top:0}.delete-modal-wrap{padding:0 4% 4rem}.delete-modal-wrap h3{font-size:3.4rem;display:inline-block;font-weight:300;margin:0 0 2rem;padding:.9rem 0 0;vertical-align:top}.delete-modal-wrap .actions{padding:3rem 0 0}.page-web-configuration .form-el-insider-wrap{width:auto}.page-web-configuration .form-el-insider{width:15.4rem}.page-web-configuration .form-el-insider-input .form-el-input{width:16.5rem}.customize-your-store .advanced-modules-count,.customize-your-store .advanced-modules-select{padding-left:1.5rem}.customize-your-store .customize-your-store-advanced{min-width:0}.customize-your-store .message-error:before{margin-top:0;top:1.8rem}.customize-your-store .message-error a{color:#333;text-decoration:underline}.customize-your-store .message-error .form-label:before{background:#fff}.customize-your-store .customize-database-clean p{margin-top:2.5rem}.content-install{margin-bottom:2rem}.console{border:1px solid #ccc;font-family:'Courier New',Courier,monospace;font-weight:300;height:20rem;margin:1rem 0 2rem;overflow-y:auto;padding:1.5rem 2rem 2rem;resize:vertical}.console .text-danger{color:#e22626}.console .text-success{color:#090}.console .hidden{display:none}.content-success .btn-prime{margin-top:1.5rem}.jumbo-title{font-size:3.6rem}.jumbo-title .jumbo-icon{font-size:3.8rem;margin-right:.25em;position:relative;top:.15em}.install-database-clean{margin-top:4rem}.install-database-clean .btn{margin-right:1rem}.page-sub-title{margin-bottom:2.1rem;margin-top:3rem}.multiselect-custom{max-width:71.1rem}.content-install{margin-top:3.7rem}.home-page-inner-wrap{margin:0 auto;max-width:91rem}.setup-home-title{margin-bottom:3.9rem;padding-top:1.8rem;text-align:center}.setup-home-item{background-color:#fafafa;border:1px solid #ccc;color:#333;display:block;margin-bottom:2rem;margin-left:1.3rem;margin-right:1.3rem;min-height:30rem;padding:2rem;text-align:center}.setup-home-item:hover{border-color:#8c8c8c;color:#333;text-decoration:none;transition:border-color .1s linear}.setup-home-item:active{-ms-transform:scale(0.99);transform:scale(0.99)}.setup-home-item:before{display:block;font-size:7rem;margin-bottom:3.3rem;margin-top:4rem}.setup-home-item-component:before,.setup-home-item-extension:before{content:'\e612'}.setup-home-item-module:before{content:'\e647'}.setup-home-item-upgrade:before{content:'\e614'}.setup-home-item-configuration:before{content:'\e610'}.setup-home-item-title{display:block;font-size:1.8rem;letter-spacing:.025em;margin-bottom:1rem}.setup-home-item-description{display:block}.extension-manager-wrap{border:1px solid #bbb;margin:0 0 4rem}.extension-manager-account{font-size:2.1rem;display:inline-block;font-weight:400}.extension-manager-title{font-size:3.2rem;background-color:#f8f8f8;border-bottom:1px solid #e3e3e3;color:#41362f;font-weight:600;line-height:1.2;padding:2rem}.extension-manager-content{padding:2.5rem 2rem 2rem}.extension-manager-items{list-style:none;margin:0;text-align:center}.extension-manager-items .btn{border:1px solid #adadad;display:block;margin:1rem auto 0}.extension-manager-items .item-title{font-size:2.1rem;display:inline-block;text-align:left}.extension-manager-items .item-number{font-size:4.1rem;display:inline-block;line-height:.8;margin:0 5px 1.5rem 0;vertical-align:top}.extension-manager-items .item-date{font-size:2.6rem;margin-top:1px}.extension-manager-items .item-date-title{font-size:1.5rem}.extension-manager-items .item-install{margin:0 0 2rem}.sync-login-wrap{padding:0 10% 4rem}.sync-login-wrap .legend{font-size:2.6rem;color:#eb5202;float:left;font-weight:300;line-height:1.2;margin:-1rem 0 2.5rem;position:static;width:100%}.sync-login-wrap .legend._hidden{display:none}.sync-login-wrap .login-header{font-size:3.4rem;font-weight:300;margin:0 0 2rem}.sync-login-wrap .login-header span{display:inline-block;padding:.9rem 0 0;vertical-align:top}.sync-login-wrap h4{font-size:1.4rem;margin:0 0 2rem}.sync-login-wrap .sync-login-steps{margin:0 0 2rem 1.5rem}.sync-login-wrap .sync-login-steps li{padding:0 0 0 1rem}.sync-login-wrap .form-row .form-label{display:inline-block}.sync-login-wrap .form-row .form-label.required{padding-left:1.5rem}.sync-login-wrap .form-row .form-label.required:after{left:0;position:absolute;right:auto}.sync-login-wrap .form-row{max-width:28rem}.sync-login-wrap .form-actions{display:table;margin-top:-1.3rem}.sync-login-wrap .form-actions .links{display:table-header-group}.sync-login-wrap .form-actions .actions{padding:3rem 0 0}@media all and (max-width:1047px){.admin__menu .submenu li{min-width:19.8rem}.nav{padding-bottom:5.38rem;padding-left:1.5rem;text-align:center}.nav-bar{display:inline-block;float:none;margin-right:0;vertical-align:top}.nav .btn-group,.nav-bar-outer-actions{display:inline-block;float:none;margin-top:-8.48rem;text-align:center;vertical-align:top;width:100%}.nav-bar-outer-actions{padding-right:0}.nav-bar-outer-actions .outer-actions-inner-wrap{display:inline-block}.app-updater .nav{padding-bottom:1.7rem}.app-updater .nav-bar-outer-actions{margin-top:2rem}}@media all and (min-width:768px){.page-layout-admin-2columns-left .page-columns{margin-left:-30px}.page-layout-admin-2columns-left .page-columns:after{clear:both;content:'';display:table}.page-layout-admin-2columns-left .page-columns .main-col{width:calc((100%) * .75 - 30px);float:right}.page-layout-admin-2columns-left .page-columns .side-col{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}.col-m-1,.col-m-10,.col-m-11,.col-m-12,.col-m-2,.col-m-3,.col-m-4,.col-m-5,.col-m-6,.col-m-7,.col-m-8,.col-m-9{float:left}.col-m-12{width:100%}.col-m-11{width:91.66666667%}.col-m-10{width:83.33333333%}.col-m-9{width:75%}.col-m-8{width:66.66666667%}.col-m-7{width:58.33333333%}.col-m-6{width:50%}.col-m-5{width:41.66666667%}.col-m-4{width:33.33333333%}.col-m-3{width:25%}.col-m-2{width:16.66666667%}.col-m-1{width:8.33333333%}.col-m-pull-12{right:100%}.col-m-pull-11{right:91.66666667%}.col-m-pull-10{right:83.33333333%}.col-m-pull-9{right:75%}.col-m-pull-8{right:66.66666667%}.col-m-pull-7{right:58.33333333%}.col-m-pull-6{right:50%}.col-m-pull-5{right:41.66666667%}.col-m-pull-4{right:33.33333333%}.col-m-pull-3{right:25%}.col-m-pull-2{right:16.66666667%}.col-m-pull-1{right:8.33333333%}.col-m-pull-0{right:auto}.col-m-push-12{left:100%}.col-m-push-11{left:91.66666667%}.col-m-push-10{left:83.33333333%}.col-m-push-9{left:75%}.col-m-push-8{left:66.66666667%}.col-m-push-7{left:58.33333333%}.col-m-push-6{left:50%}.col-m-push-5{left:41.66666667%}.col-m-push-4{left:33.33333333%}.col-m-push-3{left:25%}.col-m-push-2{left:16.66666667%}.col-m-push-1{left:8.33333333%}.col-m-push-0{left:auto}.col-m-offset-12{margin-left:100%}.col-m-offset-11{margin-left:91.66666667%}.col-m-offset-10{margin-left:83.33333333%}.col-m-offset-9{margin-left:75%}.col-m-offset-8{margin-left:66.66666667%}.col-m-offset-7{margin-left:58.33333333%}.col-m-offset-6{margin-left:50%}.col-m-offset-5{margin-left:41.66666667%}.col-m-offset-4{margin-left:33.33333333%}.col-m-offset-3{margin-left:25%}.col-m-offset-2{margin-left:16.66666667%}.col-m-offset-1{margin-left:8.33333333%}.col-m-offset-0{margin-left:0}.page-columns{margin-left:-30px}.page-columns:after{clear:both;content:'';display:table}.page-columns .page-inner-content{width:calc((100%) * .75 - 30px);float:right}.page-columns .page-inner-sidebar{width:calc((100%) * .25 - 30px);float:left;margin-left:30px}}@media all and (min-width:1048px){.col-l-1,.col-l-10,.col-l-11,.col-l-12,.col-l-2,.col-l-3,.col-l-4,.col-l-5,.col-l-6,.col-l-7,.col-l-8,.col-l-9{float:left}.col-l-12{width:100%}.col-l-11{width:91.66666667%}.col-l-10{width:83.33333333%}.col-l-9{width:75%}.col-l-8{width:66.66666667%}.col-l-7{width:58.33333333%}.col-l-6{width:50%}.col-l-5{width:41.66666667%}.col-l-4{width:33.33333333%}.col-l-3{width:25%}.col-l-2{width:16.66666667%}.col-l-1{width:8.33333333%}.col-l-pull-12{right:100%}.col-l-pull-11{right:91.66666667%}.col-l-pull-10{right:83.33333333%}.col-l-pull-9{right:75%}.col-l-pull-8{right:66.66666667%}.col-l-pull-7{right:58.33333333%}.col-l-pull-6{right:50%}.col-l-pull-5{right:41.66666667%}.col-l-pull-4{right:33.33333333%}.col-l-pull-3{right:25%}.col-l-pull-2{right:16.66666667%}.col-l-pull-1{right:8.33333333%}.col-l-pull-0{right:auto}.col-l-push-12{left:100%}.col-l-push-11{left:91.66666667%}.col-l-push-10{left:83.33333333%}.col-l-push-9{left:75%}.col-l-push-8{left:66.66666667%}.col-l-push-7{left:58.33333333%}.col-l-push-6{left:50%}.col-l-push-5{left:41.66666667%}.col-l-push-4{left:33.33333333%}.col-l-push-3{left:25%}.col-l-push-2{left:16.66666667%}.col-l-push-1{left:8.33333333%}.col-l-push-0{left:auto}.col-l-offset-12{margin-left:100%}.col-l-offset-11{margin-left:91.66666667%}.col-l-offset-10{margin-left:83.33333333%}.col-l-offset-9{margin-left:75%}.col-l-offset-8{margin-left:66.66666667%}.col-l-offset-7{margin-left:58.33333333%}.col-l-offset-6{margin-left:50%}.col-l-offset-5{margin-left:41.66666667%}.col-l-offset-4{margin-left:33.33333333%}.col-l-offset-3{margin-left:25%}.col-l-offset-2{margin-left:16.66666667%}.col-l-offset-1{margin-left:8.33333333%}.col-l-offset-0{margin-left:0}}@media all and (min-width:1440px){.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9{float:left}.col-xl-12{width:100%}.col-xl-11{width:91.66666667%}.col-xl-10{width:83.33333333%}.col-xl-9{width:75%}.col-xl-8{width:66.66666667%}.col-xl-7{width:58.33333333%}.col-xl-6{width:50%}.col-xl-5{width:41.66666667%}.col-xl-4{width:33.33333333%}.col-xl-3{width:25%}.col-xl-2{width:16.66666667%}.col-xl-1{width:8.33333333%}.col-xl-pull-12{right:100%}.col-xl-pull-11{right:91.66666667%}.col-xl-pull-10{right:83.33333333%}.col-xl-pull-9{right:75%}.col-xl-pull-8{right:66.66666667%}.col-xl-pull-7{right:58.33333333%}.col-xl-pull-6{right:50%}.col-xl-pull-5{right:41.66666667%}.col-xl-pull-4{right:33.33333333%}.col-xl-pull-3{right:25%}.col-xl-pull-2{right:16.66666667%}.col-xl-pull-1{right:8.33333333%}.col-xl-pull-0{right:auto}.col-xl-push-12{left:100%}.col-xl-push-11{left:91.66666667%}.col-xl-push-10{left:83.33333333%}.col-xl-push-9{left:75%}.col-xl-push-8{left:66.66666667%}.col-xl-push-7{left:58.33333333%}.col-xl-push-6{left:50%}.col-xl-push-5{left:41.66666667%}.col-xl-push-4{left:33.33333333%}.col-xl-push-3{left:25%}.col-xl-push-2{left:16.66666667%}.col-xl-push-1{left:8.33333333%}.col-xl-push-0{left:auto}.col-xl-offset-12{margin-left:100%}.col-xl-offset-11{margin-left:91.66666667%}.col-xl-offset-10{margin-left:83.33333333%}.col-xl-offset-9{margin-left:75%}.col-xl-offset-8{margin-left:66.66666667%}.col-xl-offset-7{margin-left:58.33333333%}.col-xl-offset-6{margin-left:50%}.col-xl-offset-5{margin-left:41.66666667%}.col-xl-offset-4{margin-left:33.33333333%}.col-xl-offset-3{margin-left:25%}.col-xl-offset-2{margin-left:16.66666667%}.col-xl-offset-1{margin-left:8.33333333%}.col-xl-offset-0{margin-left:0}}@media all and (max-width:767px){.abs-clearer-mobile:after,.nav-bar:after{clear:both;content:'';display:table}.list-definition>dt{float:none}.list-definition>dd{margin-left:0}.form-row .form-label{text-align:left}.form-row .form-label.required:after{position:static}.nav{padding-bottom:0;padding-left:0;padding-right:0}.nav-bar-outer-actions{margin-top:0}.nav-bar{display:block;margin-bottom:0;margin-left:auto;margin-right:auto;width:30.9rem}.nav-bar:before{display:none}.nav-bar>li{float:left;min-height:9rem}.nav-bar>li:after{display:none}.nav-bar>li:nth-child(4n){clear:both}.nav-bar a{line-height:1.4}.tooltip{display:none!important}.readiness-check-content{margin-right:2rem}.readiness-check-side{padding:2rem 0;position:static}.form-el-insider,.form-el-insider-wrap,.page-web-configuration .form-el-insider-input,.page-web-configuration .form-el-insider-input .form-el-input{display:block;width:100%}}@media all and (max-width:479px){.nav-bar{width:23.175rem}.nav-bar>li{width:7.725rem}.nav .btn-group .btn-wrap-try-again,.nav-bar-outer-actions .btn-wrap-try-again{clear:both;display:block;float:none;margin-left:auto;margin-right:auto;margin-top:1rem;padding-top:1rem}} \ No newline at end of file -- GitLab From 9616b80af2bf5a997601ad1c9392a65ac9ad158a Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Tue, 16 Aug 2016 13:38:23 +0300 Subject: [PATCH 378/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Magento/Sales/Api/ShipOrderInterface.php | 38 ++++ app/code/Magento/Sales/Model/ShipOrder.php | 191 ++++++++++++++++++ app/code/Magento/Sales/etc/di.xml | 1 + app/code/Magento/Sales/etc/webapi.xml | 6 + 4 files changed, 236 insertions(+) create mode 100644 app/code/Magento/Sales/Api/ShipOrderInterface.php create mode 100644 app/code/Magento/Sales/Model/ShipOrder.php diff --git a/app/code/Magento/Sales/Api/ShipOrderInterface.php b/app/code/Magento/Sales/Api/ShipOrderInterface.php new file mode 100644 index 00000000000..58f17ff7cc8 --- /dev/null +++ b/app/code/Magento/Sales/Api/ShipOrderInterface.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api; + +/** + * Class ShipOrderInterface + * + * @api + */ +interface ShipOrderInterface +{ + /** + * Creates new Shipment for given Order. + * + * @param int $orderId + * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items + * @param bool $notify + * @param bool $appendComment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks + * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments + * @return int Id of created Shipment. + */ + public function execute( + $orderId, + array $items = [], + $notify = false, + $appendComment = false, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + array $tracks = [], + array $packages = [], + \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null + ); +} diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php new file mode 100644 index 00000000000..a554b83f6b2 --- /dev/null +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -0,0 +1,191 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Api\ShipmentRepositoryInterface; +use Magento\Sales\Api\ShipOrderInterface; +use Magento\Sales\Model\Order\Config as OrderConfig; +use Magento\Sales\Model\Order\OrderStateResolverInterface; +use Magento\Sales\Model\Order\OrderValidatorInterface; +use Magento\Sales\Model\Order\ShipmentDocumentFactory; +use Magento\Sales\Model\Order\Shipment\NotifierInterface; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; +use Magento\Sales\Model\Order\ShipmentQuantityValidator; +use Magento\Sales\Model\Order\Validation\CanShip; +use Psr\Log\LoggerInterface; + +/** + * Class ShipOrder + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ShipOrder implements ShipOrderInterface +{ + /** + * @var ResourceConnection + */ + private $resourceConnection; + + /** + * @var OrderRepositoryInterface + */ + private $orderRepository; + + /** + * @var ShipmentDocumentFactory + */ + private $shipmentDocumentFactory; + + /** + * @var ShipmentValidatorInterface + */ + private $shipmentValidator; + + /** + * @var OrderStateResolverInterface + */ + private $orderStateResolver; + + /** + * @var OrderConfig + */ + private $config; + + /** + * @var ShipmentRepositoryInterface + */ + private $shipmentRepository; + + /** + * @var NotifierInterface + */ + private $notifierInterface; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var OrderValidatorInterface + */ + private $orderValidator; + + /** + * @param ResourceConnection $resourceConnection + * @param OrderRepositoryInterface $orderRepository + * @param ShipmentDocumentFactory $shipmentDocumentFactory + * @param ShipmentValidatorInterface $shipmentValidator + * @param OrderValidatorInterface $orderValidator + * @param OrderStateResolverInterface $orderStateResolver + * @param OrderConfig $config + * @param ShipmentRepositoryInterface $shipmentRepository + * @param NotifierInterface $notifierInterface + * @param LoggerInterface $logger + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + ResourceConnection $resourceConnection, + OrderRepositoryInterface $orderRepository, + ShipmentDocumentFactory $shipmentDocumentFactory, + ShipmentValidatorInterface $shipmentValidator, + OrderValidatorInterface $orderValidator, + OrderStateResolverInterface $orderStateResolver, + OrderConfig $config, + ShipmentRepositoryInterface $shipmentRepository, + NotifierInterface $notifierInterface, + LoggerInterface $logger + ) { + $this->resourceConnection = $resourceConnection; + $this->orderRepository = $orderRepository; + $this->shipmentDocumentFactory = $shipmentDocumentFactory; + $this->shipmentValidator = $shipmentValidator; + $this->orderValidator = $orderValidator; + $this->orderStateResolver = $orderStateResolver; + $this->config = $config; + $this->shipmentRepository = $shipmentRepository; + $this->notifierInterface = $notifierInterface; + $this->logger = $logger; + } + + /** + * @param int $orderId + * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items + * @param bool $notify + * @param bool $appendComment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks + * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments + * @return int + * @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface + * @throws \Magento\Sales\Api\Exception\CouldNotShipExceptionInterface + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \DomainException + */ + public function execute( + $orderId, + array $items = [], + $notify = false, + $appendComment = false, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + array $tracks = [], + array $packages = [], + \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null + ) { + $connection = $this->resourceConnection->getConnection('sales'); + $order = $this->orderRepository->get($orderId); + $shipment = $this->shipmentDocumentFactory->create( + $order, + $items, + $tracks, + $comment, + ($appendComment && $notify), + $packages, + $arguments + ); + $errorMessages = array_merge( + $this->shipmentValidator->validate( + $shipment, + [ShipmentQuantityValidator::class] + ), + $this->orderValidator->validate( + $order, + [CanShip::class] + ) + ); + if (!empty($errorMessages)) { + throw new \Magento\Sales\Exception\DocumentValidationException( + __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } + $connection->beginTransaction(); + try { + $order->setState( + $this->orderStateResolver->getStateForOrder($order, [OrderStateResolverInterface::IN_PROGRESS]) + ); + $order->setStatus($this->config->getStateDefaultStatus($order->getState())); + $this->shipmentRepository->save($shipment); + $this->orderRepository->save($order); + $connection->commit(); + } catch (\Exception $e) { + $this->logger->critical($e); + $connection->rollBack(); + throw new \Magento\Sales\Exception\CouldNotShipException( + __('Could not save a shipment, see error log for details') + ); + } + if ($notify) { + if (!$appendComment) { + $comment = null; + } + $this->notifierInterface->notify($order, $shipment, $comment); + } + return $shipment->getEntityId(); + } +} diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 5ee1fb73e1b..21a7ec666c4 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -67,6 +67,7 @@ <preference for="Magento\Sales\Api\ShipmentRepositoryInterface" type="Magento\Sales\Model\Order\ShipmentRepository"/> <preference for="Magento\Sales\Api\ShipmentManagementInterface" type="Magento\Sales\Model\Service\ShipmentService"/> <preference for="Magento\Sales\Api\ShipmentTrackRepositoryInterface" type="Magento\Sales\Api\Data\ShipmentTrack\Repository"/> + <preference for="Magento\Sales\Api\ShipOrderInterface" type="Magento\Sales\Model\ShipOrder"/> <preference for="Magento\Sales\Api\TransactionRepositoryInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Repository"/> <preference for="Magento\Sales\Model\Order\Invoice\NotifierInterface" type="Magento\Sales\Model\Order\Invoice\Notifier"/> <preference for="Magento\Sales\Model\Order\PaymentAdapterInterface" type="Magento\Sales\Model\Order\PaymentAdapter"/> diff --git a/app/code/Magento/Sales/etc/webapi.xml b/app/code/Magento/Sales/etc/webapi.xml index 8d1b1fda5bc..1dd26e55d34 100644 --- a/app/code/Magento/Sales/etc/webapi.xml +++ b/app/code/Magento/Sales/etc/webapi.xml @@ -235,6 +235,12 @@ <resource ref="Magento_Sales::sales" /> </resources> </route> + <route url="/V1/order/:orderId/ship" method="POST"> + <service class="Magento\Sales\Api\ShipOrderInterface" method="execute"/> + <resources> + <resource ref="Magento_Sales::sales" /> + </resources> + </route> <route url="/V1/orders/" method="POST"> <service class="Magento\Sales\Api\OrderRepositoryInterface" method="save"/> <resources> -- GitLab From 62a0272bfe4e0655f2ed184c82ee5118c975ff43 Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Tue, 16 Aug 2016 13:41:18 +0300 Subject: [PATCH 379/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Exception/CouldNotShipExceptionInterface.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 app/code/Magento/Sales/Api/Exception/CouldNotShipExceptionInterface.php diff --git a/app/code/Magento/Sales/Api/Exception/CouldNotShipExceptionInterface.php b/app/code/Magento/Sales/Api/Exception/CouldNotShipExceptionInterface.php new file mode 100644 index 00000000000..b52e6277912 --- /dev/null +++ b/app/code/Magento/Sales/Api/Exception/CouldNotShipExceptionInterface.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Exception; + +/** + * @api + */ +interface CouldNotShipExceptionInterface +{ +} -- GitLab From 6a4129e8d1c12909711b9ec6c83893338a93974e Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 16 Aug 2016 13:41:39 +0300 Subject: [PATCH 380/838] MAGETWO-56822: Notification messages area. Action column for notification area --- .../view/adminhtml/web/js/grid/columns/message.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js index 794a9206324..e5778f17fd1 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js @@ -14,6 +14,12 @@ define([ messageIndex: 'text', fieldClass: { message: true + }, + statusMap: { + 0: 'info', + 1: 'progress', + 2: 'success', + 3: 'error' } }, @@ -24,11 +30,13 @@ define([ /** @inheritdoc */ getFieldClass: function ($row) { - var status = $row.status || 'info'; + var status = this.statusMap[$row.status] || 'warning', + result = {}; - this.fieldClass['message-' + status] = true; + result['message-' + status] = true; + result = _.extend({}, this.fieldClass, result); - return this.fieldClass; + return result; } }); }); -- GitLab From 2354277d9058699d9581823f9861918d5b9597b4 Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Tue, 16 Aug 2016 13:51:36 +0300 Subject: [PATCH 381/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface - implement CouldNotShipException exception --- .../Sales/Exception/CouldNotShipException.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/code/Magento/Sales/Exception/CouldNotShipException.php diff --git a/app/code/Magento/Sales/Exception/CouldNotShipException.php b/app/code/Magento/Sales/Exception/CouldNotShipException.php new file mode 100644 index 00000000000..a847b7a6a8b --- /dev/null +++ b/app/code/Magento/Sales/Exception/CouldNotShipException.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Exception; + +use Magento\Framework\Exception\LocalizedException; +use Magento\Sales\Api\Exception\CouldNotShipExceptionInterface; + +/** + * Class CouldNotShipException + */ +class CouldNotInvoiceException extends LocalizedException implements CouldNotShipExceptionInterface +{ +} -- GitLab From 8965e10bb111dccbba722b326ccfd6b047ce72ef Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Tue, 16 Aug 2016 13:52:13 +0300 Subject: [PATCH 382/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/App/Action/ContextPlugin.php | 35 +++++++++---------- .../Model/App/Action/ContextPluginTest.php | 15 ++------ 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Customer/Model/App/Action/ContextPlugin.php b/app/code/Magento/Customer/Model/App/Action/ContextPlugin.php index f102664df53..7518c4b4783 100644 --- a/app/code/Magento/Customer/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Customer/Model/App/Action/ContextPlugin.php @@ -8,6 +8,10 @@ namespace Magento\Customer\Model\App\Action; use Magento\Customer\Model\Context; use Magento\Customer\Model\GroupManagement; +use Magento\Framework\App\Action\AbstractAction; +use Magento\Framework\App\RequestInterface; +use Magento\Customer\Model\Session; +use Magento\Framework\App\Http\Context as HttpContext; /** * Class ContextPlugin @@ -15,39 +19,35 @@ use Magento\Customer\Model\GroupManagement; class ContextPlugin { /** - * @var \Magento\Customer\Model\Session + * @var Session */ protected $customerSession; /** - * @var \Magento\Framework\App\Http\Context + * @var HttpContext */ protected $httpContext; /** - * @param \Magento\Customer\Model\Session $customerSession - * @param \Magento\Framework\App\Http\Context $httpContext + * @param Session $customerSession + * @param HttpContext $httpContext */ - public function __construct( - \Magento\Customer\Model\Session $customerSession, - \Magento\Framework\App\Http\Context $httpContext - ) { + public function __construct(Session $customerSession, HttpContext $httpContext) + { $this->customerSession = $customerSession; $this->httpContext = $httpContext; } /** - * @param \Magento\Framework\App\ActionInterface $subject - * @param callable $proceed - * @param \Magento\Framework\App\RequestInterface $request - * @return mixed + * Set customer group and customer session id to HTTP context + * + * @param AbstractAction $subject + * @param RequestInterface $request + * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDispatch( - \Magento\Framework\App\ActionInterface $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request - ) { + public function beforeDispatch(AbstractAction $subject, RequestInterface $request) + { $this->httpContext->setValue( Context::CONTEXT_GROUP, $this->customerSession->getCustomerGroupId(), @@ -58,6 +58,5 @@ class ContextPlugin $this->customerSession->isLoggedIn(), false ); - return $proceed($request); } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/App/Action/ContextPluginTest.php b/app/code/Magento/Customer/Test/Unit/Model/App/Action/ContextPluginTest.php index c5ab448f976..985e2ecb7ef 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/App/Action/ContextPluginTest.php @@ -28,11 +28,6 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase */ protected $httpContextMock; - /** - * @var \Closure - */ - protected $closureMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -62,9 +57,6 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase '', false ); - $this->closureMock = function () { - return 'ExpectedValue'; - }; $this->subjectMock = $this->getMock(\Magento\Framework\App\Action\Action::class, [], [], '', false); $this->requestMock = $this->getMock(\Magento\Framework\App\RequestInterface::class); $this->plugin = new \Magento\Customer\Model\App\Action\ContextPlugin( @@ -76,7 +68,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase /** * Test aroundDispatch */ - public function testAroundDispatch() + public function testBeforeDispatch() { $this->customerSessionMock->expects($this->once()) ->method('getCustomerGroupId') @@ -94,9 +86,6 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase ] ) ); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } } -- GitLab From 2f9dda6f7b7af0d7540de92f97b1eaf5476cc82a Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 14:49:18 +0300 Subject: [PATCH 383/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- app/code/Magento/Sales/Exception/CouldNotShipException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Exception/CouldNotShipException.php b/app/code/Magento/Sales/Exception/CouldNotShipException.php index a847b7a6a8b..4881bbd79a3 100644 --- a/app/code/Magento/Sales/Exception/CouldNotShipException.php +++ b/app/code/Magento/Sales/Exception/CouldNotShipException.php @@ -11,6 +11,6 @@ use Magento\Sales\Api\Exception\CouldNotShipExceptionInterface; /** * Class CouldNotShipException */ -class CouldNotInvoiceException extends LocalizedException implements CouldNotShipExceptionInterface +class CouldNotShipException extends LocalizedException implements CouldNotShipExceptionInterface { } -- GitLab From 2ee0861470a28221229f0756dd347a172ddc0741 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 14:57:24 +0300 Subject: [PATCH 384/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php | 1 + .../Magento/Sales/Model/Order/Shipment/TrackCreation.php | 5 +++-- .../Magento/Sales/Model/Order/ShipmentQuantityValidator.php | 2 +- .../Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php | 1 + .../Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php | 2 -- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php index ee0e2514535..129e55e29c3 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php @@ -28,6 +28,7 @@ class ItemCreation implements ShipmentItemCreationInterface private $extensionAttributes; //@codeCoverageIgnoreStart + /** * {@inheritdoc} */ diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index 0618ae0f6ab..6c54e0a72c1 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -161,8 +161,9 @@ class TrackCreation implements ShipmentTrackCreationInterface /** * {@inheritdoc} */ - public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes) - { + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentTrackCreationExtensionInterface $extensionAttributes + ) { $this->extensionAttributes = $extensionAttributes; return $this; } diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index b84813d1e56..ca17c1d695c 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -82,7 +82,7 @@ class ShipmentQuantityValidator implements ValidatorInterface /** * @param OrderInterface $order - * @param $id + * @param int $id * @return \Magento\Sales\Api\Data\OrderItemInterface|null */ private function getOrderItemById(OrderInterface $order, $id) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php index 8c6a3df2efd..b01a0af5e50 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php @@ -28,6 +28,7 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase * @var \Magento\Sales\Api\Data\OrderInterface|\PHPUnit_Framework_MockObject_MockObject */ private $orderMock; + /** * @var \Magento\Sales\Api\OrderRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php index 30ae7101209..4d3bad7a377 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -1,5 +1,4 @@ <?php - /** * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. @@ -71,7 +70,6 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase ->setMethods(['addComment']) ->getMockForAbstractClass(); - $this->invoiceDocumentFactory = new ShipmentDocumentFactory($this->shipmentFactoryMock); } -- GitLab From 8455f454208d39804586a1451b275c7c3de3ea96 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 15:01:09 +0300 Subject: [PATCH 385/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php | 2 +- app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php | 3 ++- .../Sales/Test/Unit/Model/Order/Validation/CanShipTest.php | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php index 129e55e29c3..e3cb2f23d7c 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/ItemCreation.php @@ -28,7 +28,7 @@ class ItemCreation implements ShipmentItemCreationInterface private $extensionAttributes; //@codeCoverageIgnoreStart - + /** * {@inheritdoc} */ diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index dffff83b97f..106882418ab 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -32,7 +32,8 @@ class CanInvoice implements ValidatorInterface * @param OrderInterface $order * @return bool */ - private function canInvoice(OrderInterface $order) { + private function canInvoice(OrderInterface $order) + { if ($order->getState() === Order::STATE_PAYMENT_REVIEW || $order->getState() === Order::STATE_HOLDED || $order->getState() === Order::STATE_CANCELED || diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php index c31fd28b7b4..439e322b9c3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php @@ -120,7 +120,8 @@ class CanShipTest extends \PHPUnit_Framework_TestCase ->willReturn($itemLockedDoShipment); $this->assertEquals( - $expectedResult, $this->model->validate($this->orderMock) + $expectedResult, + $this->model->validate($this->orderMock) ); } -- GitLab From 0a812ebec7e0d0dbc8475f18a0d1c4900c2ab7dd Mon Sep 17 00:00:00 2001 From: Olha Nakonechna <onakonechna@magento.com> Date: Tue, 16 Aug 2016 15:07:50 +0300 Subject: [PATCH 386/838] MAGETWO-53135: [GITHUB] Prices of related products on PDP changes according to product custom options. #4588 --- .../Catalog/view/frontend/templates/product/view/form.phtml | 2 +- .../Catalog/view/frontend/templates/product/view/options.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index f23544a7734..f27f9ecea45 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -43,7 +43,7 @@ 'Magento_Catalog/js/price-box' ], function($){ var dataPriceBoxSelector = '[data-role=priceBox]', - dataProductIdSelector = '[data-product-id=<?php echo $block->escapeHtml($_product->getId());?>]', + dataProductIdSelector = '[data-product-id=<?php echo $block->escapeHtml($_product->getId())?>]', priceBoxes = $(dataPriceBoxSelector + dataProductIdSelector); priceBoxes = priceBoxes.filter(function(index, elem){ diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml index ec8f3c86483..e7918f7da37 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml @@ -18,7 +18,7 @@ "priceOptions": { "optionConfig": <?php /* @escapeNotVerified */ echo $block->getJsonConfig()?>, "controlContainer": ".field", - "priceHolderSelector": "[data-product-id='<?php echo $_productId?>'][data-role=priceBox]" + "priceHolderSelector": "[data-product-id='<?php echo /* @noEscape */ $_productId?>'][data-role=priceBox]" } } } -- GitLab From f495bcd414bd99a97a262ce0df5db5e121e50507 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Tue, 16 Aug 2016 15:11:00 +0300 Subject: [PATCH 387/838] MAGETWO-56778: Value for multiple select attribute does not save -- fixes after CR --- .../Eav/Model/Entity/AttributeLoader.php | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index af6b88fe089..a9d22b35d62 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -62,17 +62,10 @@ class AttributeLoader implements AttributeLoaderInterface * @return AbstractEntity * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function loadAllAttributes(AbstractEntity $resource, DataObject $object = null) { - $attributeSetId = 0; - $storeId = 0; - if ($object instanceof \Magento\Framework\DataObject) { - $attributeSetId = $object->getAttributeSetId() ?: $attributeSetId; - $storeId = $object->getStoreId() ?: $storeId; - } - $suffix = $storeId . '-' . $attributeSetId; + $suffix = $this->getLoadAllAttributesCacheSuffix(); $typeCode = $resource->getEntityType()->getEntityTypeCode(); $attributes = $this->cache->getAttributes($typeCode, $suffix); @@ -109,6 +102,22 @@ class AttributeLoader implements AttributeLoaderInterface return $resource; } + /** + * @param DataObject|null $object + * @return string + */ + private function getLoadAllAttributesCacheSuffix(DataObject $object = null) + { + $attributeSetId = 0; + $storeId = 0; + if (null !== $object) { + $attributeSetId = $object->getAttributeSetId() ?: $attributeSetId; + $storeId = $object->getStoreId() ?: $storeId; + } + $suffix = $storeId . '-' . $attributeSetId; + return $suffix; + } + /** * Return default static virtual attribute that doesn't exists in EAV attributes * -- GitLab From 8fb6410688e6bf5fadf7288f7471197172657c45 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 16 Aug 2016 15:12:43 +0300 Subject: [PATCH 388/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Category/Plugin/Store/Group.php | 12 +- .../Model/Category/Plugin/Store/GroupTest.php | 183 ++++++++++++++++++ 2 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php index f3c86bad499..c290d10296e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php @@ -63,19 +63,17 @@ class Group } /** - * @param \Magento\Store\Model\ResourceModel\Group $object - * @param callable $proceed + * @param \Magento\Store\Model\ResourceModel\Group $subject + * @param \Magento\Store\Model\ResourceModel\Group $result * @param AbstractModel $group * @return \Magento\Store\Model\ResourceModel\Group * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundSave( - \Magento\Store\Model\ResourceModel\Group $object, - \Closure $proceed, + public function afterSave( + \Magento\Store\Model\ResourceModel\Group $subject, + \Magento\Store\Model\ResourceModel\Group $result, AbstractModel $group ) { - $originGroup = $group; - $result = $proceed($originGroup); if (!$group->isObjectNew() && ($group->dataHasChangedFor('website_id') || $group->dataHasChangedFor('root_category_id')) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php new file mode 100644 index 00000000000..d22cdabef64 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php @@ -0,0 +1,183 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Store; + +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\Group as GroupPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Model\AbstractModel; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Model\ResourceModel\Group; +use Magento\Catalog\Model\Category; +use Magento\Catalog\Model\CategoryFactory; +use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; +use Magento\Catalog\Model\Product as Product; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Catalog\Model\ProductFactory; + +use Magento\Store\Model\ResourceModel\Store; +use Magento\UrlRewrite\Model\UrlPersistInterface; + +use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; + + + + +class GroupTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var GroupPlugin + */ + private $plugin; + + /** + * @var AbstractModel|\PHPUnit_Framework_MockObject_MockObject + */ + private $abstractModelMock; + + /** + * @var Group|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectMock; + + /** + * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $storeManagerMock; + + /** + * @var CategoryFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryFactoryMock; + + /** + * @var Category|\PHPUnit_Framework_MockObject_MockObject + */ + private $categoryMock; + + /** + * @var ProductCollection|\PHPUnit_Framework_MockObject_MockObject + */ + private $productCollectionMock; + + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $productMock; + + /** + * @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $productFactoryMock; + + /** + * @var ProductUrlRewriteGenerator|\PHPUnit_Framework_MockObject_MockObject + */ + private $productUrlRewriteGeneratorMock; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->abstractModelMock = $this->getMockBuilder(AbstractModel::class) + ->disableOriginalConstructor() + ->setMethods(['isObjectNew', 'dataHasChangedFor', 'getStoreIds']) + ->getMockForAbstractClass(); + $this->abstractModelMock->expects($this->any()) + ->method('getStoreIds') + ->willReturn([]); + $this->subjectMock = $this->getMockBuilder(Group::class) + ->disableOriginalConstructor() + ->getMock(); + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) + ->disableOriginalConstructor() + ->setMethods(['reinitStores']) + ->getMockForAbstractClass(); + $this->categoryMock = $this->getMockBuilder(Category::class) + ->disableOriginalConstructor() + ->setMethods(['getCategories']) + ->getMock(); + $this->categoryFactoryMock = $this->getMockBuilder(CategoryFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->productFactoryMock = $this->getMockBuilder(ProductFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->productCollectionMock = $this->getMockBuilder(ProductCollection::class) + ->disableOriginalConstructor() + ->setMethods(['addCategoryIds', 'addAttributeToSelect', 'addWebsiteFilter', 'getIterator']) + ->getMock(); + $this->productMock = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getCollection']) + ->getMock(); + $this->productUrlRewriteGeneratorMock = $this->getMockBuilder(ProductUrlRewriteGenerator::class) + ->disableOriginalConstructor() + ->setMethods(['generate']) + ->getMock(); + $this->plugin = $this->objectManager->getObject( + GroupPlugin::class, + [ + 'storeManager' => $this->storeManagerMock, + 'categoryFactory' => $this->categoryFactoryMock, + 'productFactory' => $this->productFactoryMock, + 'productUrlRewriteGenerator' => $this->productUrlRewriteGeneratorMock + ] + ); + } + + public function testAfterSave() + { + $this->abstractModelMock->expects($this->once()) + ->method('isObjectNew') + ->willReturn(false); + $this->abstractModelMock->expects($this->once()) + ->method('dataHasChangedFor') + ->with('website_id') + ->willReturn(true); + $this->storeManagerMock->expects($this->once()) + ->method('reinitStores'); + $this->categoryMock->expects($this->once()) + ->method('getCategories') + ->willReturn([]); + $this->categoryFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->categoryMock); + $this->productFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->productMock); + $this->productMock->expects($this->once()) + ->method('getCollection') + ->willReturn($this->productCollectionMock); + $this->productCollectionMock->expects($this->once()) + ->method('addCategoryIds') + ->willReturn($this->productCollectionMock); + $this->productCollectionMock->expects($this->once()) + ->method('addAttributeToSelect') + ->willReturn($this->productCollectionMock); + $this->productCollectionMock->expects($this->once()) + ->method('addWebsiteFilter') + ->willReturn($this->productCollectionMock); + $iterator = new \ArrayIterator([$this->productMock]); + $this->productCollectionMock->expects($this->once()) + ->method('getIterator') + ->willReturn($iterator); + $this->productUrlRewriteGeneratorMock->expects($this->once()) + ->method('generate') + ->with($this->productMock) + ->willReturn([]); + + $this->assertEquals( + $this->subjectMock, + $this->plugin->afterSave($this->subjectMock, $this->subjectMock, $this->abstractModelMock) + ); + } +} -- GitLab From 36a9201b548d5720d0ad9ad3f7a4063a9446b3ce Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Tue, 16 Aug 2016 16:22:18 +0300 Subject: [PATCH 389/838] MAGETWO-56778: Value for multiple select attribute does not save -- fixes after CR --- app/code/Magento/Eav/Model/Entity/AttributeLoader.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index a9d22b35d62..a4fab29dba0 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -61,7 +61,6 @@ class AttributeLoader implements AttributeLoaderInterface * @param DataObject|null $object * @return AbstractEntity * @throws \Magento\Framework\Exception\LocalizedException - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function loadAllAttributes(AbstractEntity $resource, DataObject $object = null) { -- GitLab From ef9c96c06a3b108254150d530f3fb7db1f64e278 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 16:31:24 +0300 Subject: [PATCH 390/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Magento/Sales/Api/Data/TrackInterface.php | 17 +++++++++++++++++ .../Model/Order/Validation/CanInvoiceTest.php | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Api/Data/TrackInterface.php b/app/code/Magento/Sales/Api/Data/TrackInterface.php index d082f6ca5e0..2a43b92fe68 100644 --- a/app/code/Magento/Sales/Api/Data/TrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/TrackInterface.php @@ -102,4 +102,21 @@ interface TrackInterface extends \Magento\Framework\Api\ExtensibleDataInterface * @return string Carrier code. */ public function getCarrierCode(); + + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\TrackExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\TrackExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\TrackExtensionInterface $extensionAttributes + ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php index dae95c4a758..b0704fcb01d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Sales\Test\Unit\Model\Order\Invoice\Validator; +namespace Magento\Sales\Test\Unit\Model\Order\Validation; use Magento\Sales\Model\Order; -- GitLab From dfdfd6468f768f2bf9e807095d9f0fac99bda980 Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Tue, 16 Aug 2016 16:36:46 +0300 Subject: [PATCH 391/838] MAGETWO-56495: Introduce and implement ShipmentNotifier --- app/code/Magento/Sales/etc/di.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 21a7ec666c4..daf2a69a619 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -70,6 +70,7 @@ <preference for="Magento\Sales\Api\ShipOrderInterface" type="Magento\Sales\Model\ShipOrder"/> <preference for="Magento\Sales\Api\TransactionRepositoryInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Repository"/> <preference for="Magento\Sales\Model\Order\Invoice\NotifierInterface" type="Magento\Sales\Model\Order\Invoice\Notifier"/> + <preference for="Magento\Sales\Model\Order\Shipment\NotifierInterface" type="Magento\Sales\Model\Order\Shipment\Notifier"/> <preference for="Magento\Sales\Model\Order\PaymentAdapterInterface" type="Magento\Sales\Model\Order\PaymentAdapter"/> <preference for="Magento\Sales\Model\Order\Payment\Transaction\ManagerInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Manager"/> <preference for="Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface" type="Magento\Sales\Model\Order\Payment\Transaction\Builder"/> @@ -917,4 +918,11 @@ </argument> </arguments> </type> + <type name="Magento\Sales\Model\Order\Shipment\Notifier"> + <arguments> + <argument name="senders" xsi:type="array"> + <item name="email" xsi:type="object">Magento\Sales\Model\Order\Shipment\Sender\EmailSender</item> + </argument> + </arguments> + </type> </config> -- GitLab From a70cc719ede56d0465f4bc08c77c9ad5b1d29d24 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Tue, 16 Aug 2016 16:37:45 +0300 Subject: [PATCH 392/838] MAGETWO-56778: Value for multiple select attribute does not save -- fix static tests --- .../Magento/Eav/Model/Entity/AttributeLoader.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index a4fab29dba0..e369ded310b 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -74,9 +74,22 @@ class AttributeLoader implements AttributeLoaderInterface } return $resource; } + $attributes = $this->checkAndInitAttributes($resource, $object); + $this->cache->saveAttributes($typeCode, $attributes, $suffix); + return $resource; + } + + /** + * @param AbstractEntity $resource + * @param DataObject|null $object + * @return array + */ + private function checkAndInitAttributes(AbstractEntity $resource, DataObject $object = null) + { $attributeCodes = $this->config->getEntityAttributeCodes($resource->getEntityType(), $object); $attributes = []; + /** * Check and init default attributes */ @@ -97,8 +110,7 @@ class AttributeLoader implements AttributeLoaderInterface $attribute = $resource->getAttribute($code); $attributes[] = $attribute; } - $this->cache->saveAttributes($typeCode, $attributes, $suffix); - return $resource; + return $attributes; } /** -- GitLab From 3577e43e5812b1ef13ea4ff8c728152b1ef0a293 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 16:37:51 +0300 Subject: [PATCH 393/838] MAGETWO-54677: Order status change after Shipment creation through API - redundant validation remove --- .../Sales/Model/Order/Shipment/Item.php | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index ec1b2940fbf..c8bdac365cc 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -9,10 +9,8 @@ namespace Magento\Sales\Model\Order\Shipment; use Magento\Framework\Api\AttributeValueFactory; -use Magento\Framework\App\ObjectManager; use Magento\Sales\Api\Data\ShipmentItemInterface; use Magento\Sales\Model\AbstractModel; -use Magento\Sales\Model\Order\ShipmentQuantityValidator; /** * @method \Magento\Sales\Model\ResourceModel\Order\Shipment\Item _getResource() @@ -170,32 +168,10 @@ class Item extends AbstractModel implements ShipmentItemInterface */ public function register() { - $errorMessages = $this->getShipmentValidator()->validate( - $this->getShipment(), - [ShipmentQuantityValidator::class] - ); - if (!empty($errorMessages)) { - throw new \Magento\Framework\Exception\LocalizedException( - __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) - ); - } $this->getOrderItem()->setQtyShipped($this->getOrderItem()->getQtyShipped() + $this->getQty()); return $this; } - /** - * @return ShipmentValidatorInterface - * @deprecated - */ - private function getShipmentValidator() - { - if ($this->shipmentValidator === null) { - $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); - } - - return $this->shipmentValidator; - } - //@codeCoverageIgnoreStart /** * Returns additional_data -- GitLab From 1bfe96185af968bca2de6d9d112c7343c4710a85 Mon Sep 17 00:00:00 2001 From: Olha Nakonechna <onakonechna@magento.com> Date: Tue, 16 Aug 2016 16:41:35 +0300 Subject: [PATCH 394/838] MAGETWO-53135: [GITHUB] Prices of related products on PDP changes according to product custom options. #4588 --- .../Catalog/view/frontend/templates/product/view/options.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml index e7918f7da37..9da72303f06 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options.phtml @@ -18,7 +18,7 @@ "priceOptions": { "optionConfig": <?php /* @escapeNotVerified */ echo $block->getJsonConfig()?>, "controlContainer": ".field", - "priceHolderSelector": "[data-product-id='<?php echo /* @noEscape */ $_productId?>'][data-role=priceBox]" + "priceHolderSelector": "[data-product-id='<?php echo $block->escapeHtml($_productId)?>'][data-role=priceBox]" } } } -- GitLab From 98537ad8c3abd720cbe3f7646ee6769bc316a2da Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 16:43:29 +0300 Subject: [PATCH 395/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 8 ++++++++ .../Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php | 7 ++----- .../Test/Unit/Model/Order/Validation/CanInvoiceTest.php | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 6509aacd932..5a263ea1795 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -21,8 +21,15 @@ use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; */ class ShipmentDocumentFactory { + /** + * @var ShipmentFactory + */ private $shipmentFactory; + /** + * ShipmentDocumentFactory constructor. + * @param ShipmentFactory $shipmentFactory + */ public function __construct( ShipmentFactory $shipmentFactory ) { @@ -37,6 +44,7 @@ class ShipmentDocumentFactory * @param bool $appendComment * @param array $packages * @return Shipment + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function create( OrderInterface $order, diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php index df35aae943e..4461e16b672 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php @@ -5,9 +5,6 @@ */ namespace Magento\Sales\Test\Unit\Model\Order; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; - /** * Unit test for shipment factory class. */ @@ -45,7 +42,7 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase */ protected function setUp() { - $objectManager = new ObjectManager($this); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->converter = $this->getMock( \Magento\Sales\Model\Convert\Order::class, @@ -74,7 +71,7 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase false ); $this->shipmentValidatorMock = $this->getMockBuilder( - ShipmentValidatorInterface::class + \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface::class )->getMockForAbstractClass(); $this->subject = $objectManager->getObject( diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php index b0704fcb01d..f3d93d73474 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php @@ -122,7 +122,8 @@ class CanInvoiceTest extends \PHPUnit_Framework_TestCase ->willReturn($itemLockedDoInvoice); $this->assertEquals( - $expectedResult, $this->model->validate($this->orderMock) + $expectedResult, + $this->model->validate($this->orderMock) ); } -- GitLab From a3584889ac047672ff2da9d9747854204b12640a Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 16:48:53 +0300 Subject: [PATCH 396/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Magento/Sales/Api/Data/TrackInterface.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/TrackInterface.php b/app/code/Magento/Sales/Api/Data/TrackInterface.php index 2a43b92fe68..d082f6ca5e0 100644 --- a/app/code/Magento/Sales/Api/Data/TrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/TrackInterface.php @@ -102,21 +102,4 @@ interface TrackInterface extends \Magento\Framework\Api\ExtensibleDataInterface * @return string Carrier code. */ public function getCarrierCode(); - - /** - * Retrieve existing extension attributes object or create a new one. - * - * @return \Magento\Sales\Api\Data\TrackExtensionInterface|null - */ - public function getExtensionAttributes(); - - /** - * Set an extension attributes object. - * - * @param \Magento\Sales\Api\Data\TrackExtensionInterface $extensionAttributes - * @return $this - */ - public function setExtensionAttributes( - \Magento\Sales\Api\Data\TrackExtensionInterface $extensionAttributes - ); } -- GitLab From c5208159c836b2f03a3ab14909bd26fa5041db98 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 16:51:42 +0300 Subject: [PATCH 397/838] MAGETWO-54677: Order status change after Shipment creation through API - redundant validation remove --- .../Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php | 4 +++- app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php | 4 +++- app/code/Magento/Sales/Api/Data/TrackInterface.php | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php index f3c3347534a..6a45242fcd1 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackCreationInterface.php @@ -6,12 +6,14 @@ */ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Shipment Track Creation interface. * * @api */ -interface ShipmentTrackCreationInterface extends TrackInterface +interface ShipmentTrackCreationInterface extends TrackInterface, ExtensibleDataInterface { /** * Retrieve existing extension attributes object or create a new one. diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php index c6c610433cb..c5ba339bf02 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php @@ -5,6 +5,8 @@ */ namespace Magento\Sales\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Shipment track interface. * @@ -13,7 +15,7 @@ namespace Magento\Sales\Api\Data; * shipments. * @api */ -interface ShipmentTrackInterface extends TrackInterface +interface ShipmentTrackInterface extends TrackInterface, ExtensibleDataInterface { /**#@+ * Constants for keys of data array. Identical to the name of the getter in snake case. diff --git a/app/code/Magento/Sales/Api/Data/TrackInterface.php b/app/code/Magento/Sales/Api/Data/TrackInterface.php index d082f6ca5e0..075d6b45182 100644 --- a/app/code/Magento/Sales/Api/Data/TrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/TrackInterface.php @@ -11,7 +11,7 @@ namespace Magento\Sales\Api\Data; * * @api */ -interface TrackInterface extends \Magento\Framework\Api\ExtensibleDataInterface +interface TrackInterface { /** * Sets the weight for the shipment package. -- GitLab From 8fcdede9a29d2e061d96a9f4d5eeba66d030f772 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 16 Aug 2016 17:23:39 +0300 Subject: [PATCH 398/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Product/Link/RelationPersister.php | 46 ++++++----- .../Product/Link/RelationPersisterTest.php | 81 +++++++++++++------ 2 files changed, 85 insertions(+), 42 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php index f83b34ec3b3..4fb61cf7b16 100644 --- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php +++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php @@ -9,6 +9,8 @@ namespace Magento\GroupedProduct\Model\ResourceModel\Product\Link; use Magento\Catalog\Model\ProductLink\LinkFactory; use Magento\Catalog\Model\ResourceModel\Product\Link; use Magento\Catalog\Model\ResourceModel\Product\Relation; +use Magento\Catalog\Model\ProductLink\Link as ProductLink; +use Magento\GroupedProduct\Model\ResourceModel\Product\Link as GroupedLink; class RelationPersister { @@ -22,6 +24,11 @@ class RelationPersister */ private $linkFactory; + /** + * @var ProductLink + */ + private $link; + /** * RelationPersister constructor. * @@ -35,20 +42,17 @@ class RelationPersister } /** - * Save grouped products to product relation table - * * @param Link $subject - * @param \Closure $proceed + * @param Link $result * @param int $parentId * @param array $data * @param int $typeId * @return Link * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundSaveProductLinks(Link $subject, \Closure $proceed, $parentId, $data, $typeId) + public function afterSaveProductLinks(Link $subject, Link $result, $parentId, array $data, $typeId) { - $result = $proceed($parentId, $data, $typeId); - if ($typeId == \Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED) { + if ($typeId == GroupedLink::LINK_TYPE_GROUPED) { foreach ($data as $linkData) { $this->relationProcessor->addRelation( $parentId, @@ -60,23 +64,29 @@ class RelationPersister } /** - * Remove grouped products from product relation table - * * @param Link $subject - * @param \Closure $proceed * @param int $linkId - * @return Link + * @return array + */ + public function beforeDeleteProductLink(Link $subject, $linkId) + { + $this->link = $this->linkFactory->create(); + $subject->load($this->link, $linkId, $subject->getIdFieldName()); + return [$linkId]; + } + + /** + * @param Link $subject + * @param int $result + * @return int + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDeleteProductLink(Link $subject, \Closure $proceed, $linkId) + public function afterDeleteProductLink(Link $subject, $result) { - /** @var \Magento\Catalog\Model\ProductLink\Link $link */ - $link = $this->linkFactory->create(); - $subject->load($link, $linkId, $subject->getIdFieldName()); - $result = $proceed($linkId); - if ($link->getLinkTypeId() == \Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED) { + if ($this->link->getLinkTypeId() == GroupedLink::LINK_TYPE_GROUPED) { $this->relationProcessor->removeRelations( - $link->getProductId(), - $link->getLinkedProductId() + $this->link->getProductId(), + $this->link->getLinkedProductId() ); } return $result; diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php index d11539945b0..0cf327fd459 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php @@ -3,13 +3,14 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\GroupedProduct\Test\Unit\Model\ResourceModel\Product\Link; use Magento\GroupedProduct\Model\ResourceModel\Product\Link\RelationPersister; use Magento\Catalog\Model\ProductLink\LinkFactory; use Magento\Catalog\Model\Product\Link; use Magento\Catalog\Model\ResourceModel\Product\Relation; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Catalog\Model\ResourceModel\Product\Link as ResourceLink; class RelationPersisterTest extends \PHPUnit_Framework_TestCase { @@ -22,12 +23,27 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase /** @var Relation */ private $relationProcessor; + /** @var ObjectManager */ + private $objectManager; + + /** + * @var LinkFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $linkFactory; + + /** + * @var ResourceLink|\PHPUnit_Framework_MockObject_MockObject + */ + private $subject; + /** * @inheritDoc */ protected function setUp() { - $linkFactory = $this->getMockBuilder(LinkFactory::class) + $this->objectManager = new ObjectManager($this); + + $this->linkFactory = $this->getMockBuilder(LinkFactory::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); @@ -41,37 +57,56 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $linkFactory->expects($this->any())->method('create')->willReturn($this->link); + $this->linkFactory->expects($this->any())->method('create')->willReturn($this->link); + + $this->subject = $this->getMockBuilder(ResourceLink::class) + ->disableOriginalConstructor() + ->getMock(); - $this->object = new RelationPersister( - $this->relationProcessor, - $linkFactory + $this->object = $this->objectManager->getObject( + RelationPersister::class, + [ + 'relationProcessor' => $this->relationProcessor, + 'linkFactory' => $this->linkFactory + ] ); } - public function testAroundSaveProductLinks() + public function testAfterSaveProductLinks() { - $subject = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Link::class) - ->disableOriginalConstructor() - ->getMock(); $this->relationProcessor->expects($this->once())->method('addRelation')->with(2, 10); - $this->assertEquals($subject, $this->object->aroundSaveProductLinks( - $subject, - function() use ($subject) { return $subject; }, + $this->assertEquals($this->subject, $this->object->afterSaveProductLinks( + $this->subject, + $this->subject, 2, [['product_id' => 10]], 3 )); } - public function testAroundDeleteProductLink() + public function testBeforeDeleteProductLink() { - $subject = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Link::class) - ->disableOriginalConstructor() - ->getMock(); - $subject->expects($this->any())->method('getIdFieldName')->willReturn('id'); - $subject->expects($this->once())->method('load')->with($this->link, 155, 'id'); + $this->subject->expects($this->any())->method('getIdFieldName')->willReturn('id'); + $this->subject->expects($this->once())->method('load')->with($this->link, 155, 'id'); + $this->assertEquals( + [155], + $this->object->beforeDeleteProductLink( + $this->subject, + 155 + ) + ); + } + public function testAfterDeleteProductLink() + { + $object = $this->objectManager->getObject( + RelationPersister::class, + [ + 'relationProcessor' => $this->relationProcessor, + 'linkFactory' => $this->linkFactory, + 'link' => $this->link + ] + ); $this->link->expects($this->any()) ->method('getLinkTypeId') ->willReturn(\Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED); @@ -84,13 +119,11 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase $this->relationProcessor->expects($this->once())->method('removeRelations')->with(12, 13); $this->assertEquals( - $subject, - $this->object->aroundDeleteProductLink( - $subject, - function() use ($subject) { return $subject; }, + 155, + $object->afterDeleteProductLink( + $this->subject, 155 ) ); - } } -- GitLab From 685619310852d1c68d078633f7d0d4fec6caf011 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Tue, 16 Aug 2016 17:33:04 +0300 Subject: [PATCH 399/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Block/Adminhtml/Store/SwitcherPlugin.php | 24 +++---- .../Adminhtml/Store/SwitcherPluginTest.php | 66 ++++++++++++++----- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php b/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php index 3af4493e61e..3d48ee060f3 100644 --- a/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php +++ b/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php @@ -5,26 +5,28 @@ */ namespace Magento\Paypal\Block\Adminhtml\Store; +use Magento\Backend\Block\Store\Switcher as StoreSwitcherBlock; +use Magento\Paypal\Model\Config\StructurePlugin as ConfigStructurePlugin; + +/** + * Plugin for \Magento\Backend\Block\Store\Switcher + */ class SwitcherPlugin { /** * Remove country request param from url * - * @param \Magento\Backend\Block\Store\Switcher $subject - * @param \Closure $proceed + * @param StoreSwitcherBlock $subject * @param string $route * @param array $params * @return string */ - public function aroundGetUrl( - \Magento\Backend\Block\Store\Switcher $subject, - \Closure $proceed, - $route = '', - $params = [] - ) { - if ($subject->getRequest()->getParam(\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY)) { - $params[\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY] = null; + public function beforeGetUrl(StoreSwitcherBlock $subject, $route = '', $params = []) + { + if ($subject->getRequest()->getParam(ConfigStructurePlugin::REQUEST_PARAM_COUNTRY)) { + $params[ConfigStructurePlugin::REQUEST_PARAM_COUNTRY] = null; } - return $proceed($route, $params); + + return [$route, $params]; } } diff --git a/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/Store/SwitcherPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/Store/SwitcherPluginTest.php index 320e89d567b..a97fb0ad2a6 100644 --- a/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/Store/SwitcherPluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Block/Adminhtml/Store/SwitcherPluginTest.php @@ -5,42 +5,72 @@ */ namespace Magento\Paypal\Test\Unit\Block\Adminhtml\Store; +use Magento\Paypal\Block\Adminhtml\Store\SwitcherPlugin as StoreSwitcherBlockPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Backend\Block\Store\Switcher as StoreSwitcherBlock; +use Magento\Framework\App\RequestInterface; +use Magento\Paypal\Model\Config\StructurePlugin as ConfigStructurePlugin; + class SwitcherPluginTest extends \PHPUnit_Framework_TestCase { /** - * @var SwitcherPlugin + * @var StoreSwitcherBlockPlugin + */ + private $plugin; + + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + /** + * @var StoreSwitcherBlock|\PHPUnit_Framework_MockObject_MockObject */ - protected $_model; + private $subjectMock; + + /** + * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; protected function setUp() { - $this->_model = new \Magento\Paypal\Block\Adminhtml\Store\SwitcherPlugin(); + $this->subjectMock = $this->getMockBuilder(StoreSwitcherBlock::class) + ->disableOriginalConstructor() + ->getMock(); + $this->requestMock = $this->getMockBuilder(RequestInterface::class) + ->getMockForAbstractClass(); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject(StoreSwitcherBlockPlugin::class); } /** - * @param null|string $countryParam + * @param string|null $countryParam * @param array $getUrlParams - * @dataProvider aroundGetUrlDataProvider + * + * @dataProvider beforeGetUrlDataProvider */ - public function testAroundGetUrl($countryParam, $getUrlParams) + public function testBeforeGetUrl($countryParam, $getUrlParams) { - $subjectRequest = $this->getMockForAbstractClass(\Magento\Framework\App\RequestInterface::class); - $subjectRequest->expects($this->once()) + $this->requestMock->expects(static::once()) ->method('getParam') - ->with(\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY) - ->will($this->returnValue($countryParam)); - $subject = $this->getMock(\Magento\Backend\Block\Store\Switcher::class, ['getRequest'], [], '', false); - $subject->expects($this->any())->method('getRequest')->will($this->returnValue($subjectRequest)); - $getUrl = function ($route, $params) { - return [$route, $params]; - }; - $this->assertEquals(['', $getUrlParams], $this->_model->aroundGetUrl($subject, $getUrl, '', [])); + ->with(ConfigStructurePlugin::REQUEST_PARAM_COUNTRY) + ->willReturn($countryParam); + $this->subjectMock->expects(static::any()) + ->method('getRequest') + ->willReturn($this->requestMock); + + $this->assertEquals(['', $getUrlParams], $this->plugin->beforeGetUrl($this->subjectMock, '', [])); } - public function aroundGetUrlDataProvider() + /** + * @return array + */ + public function beforeGetUrlDataProvider() { return [ - ['any value', [\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY => null]], + ['any value', [ConfigStructurePlugin::REQUEST_PARAM_COUNTRY => null]], [null, []] ]; } -- GitLab From cdb77aa0a3e3e6353a8dcde4c92e8057cbc10570 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko <skovalenko@magento.com> Date: Tue, 16 Aug 2016 17:42:23 +0300 Subject: [PATCH 400/838] MAGETWO-24139: Resolve Customer TODO`s --- .../Test/Unit/Model/AttributeMetadatConverterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php b/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php index 9298e27d94e..c7182a51651 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AttributeMetadatConverterTest.php @@ -148,8 +148,8 @@ class AttributeMetadatConverterTest extends \PHPUnit_Framework_TestCase $this->dataObjectHelper->expects($this->exactly(2)) ->method('populateWithArray') ->withConsecutive( - [$optionObject1, ['1'], 'Magento\Customer\Api\Data\OptionInterface'], - [$optionObject2, ['2'], 'Magento\Customer\Api\Data\OptionInterface'] + [$optionObject1, ['1'], \Magento\Customer\Api\Data\OptionInterface::class], + [$optionObject2, ['2'], \Magento\Customer\Api\Data\OptionInterface::class] ); $validationRule1 = $this->getMock(\Magento\Customer\Api\Data\ValidationRuleInterface::class); $validationRule2 = $this->getMock(\Magento\Customer\Api\Data\ValidationRuleInterface::class); -- GitLab From 44641bd2011a55f70b56099c58f18a71b05089db Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Tue, 16 Aug 2016 18:00:11 +0300 Subject: [PATCH 401/838] MAGETWO-52280: "Tier Price" field is unexpectedly marked as required on "create Product" Admin page --- .../Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 3b92e54355f..e56c326e994 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -420,6 +420,7 @@ class AdvancedPricing extends AbstractModifier 'enabled' => false, ], 'disabled' => false, + 'required' => false, 'sortOrder' => $this->arrayManager->get($tierPricePath . '/arguments/data/config/sortOrder', $this->meta), ], -- GitLab From 61dcb9922e0db8e8b744eeb305562a8bf5e4b881 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 18:08:56 +0300 Subject: [PATCH 402/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/Order/Shipment/Item.php | 5 ----- app/code/Magento/Sales/Model/Order/ShipmentFactory.php | 1 + .../Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php | 1 + .../Sales/Test/Unit/Model/Order/Validation/CanShipTest.php | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index c8bdac365cc..8627f76031b 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -44,11 +44,6 @@ class Item extends AbstractModel implements ShipmentItemInterface */ protected $_orderItemFactory; - /** - * @var ShipmentValidatorInterface - */ - private $shipmentValidator; - /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 518f3909cd7..dc03ebc191e 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -82,6 +82,7 @@ class ShipmentFactory * @param array $items * @return \Magento\Sales\Api\Data\ShipmentInterface * @throws LocalizedException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function prepareItems( \Magento\Sales\Api\Data\ShipmentInterface $shipment, diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php index 4461e16b672..3c1ed06f9b9 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Test\Unit\Model\Order; /** * Unit test for shipment factory class. + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase { diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php index 439e322b9c3..44345372600 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Sales\Test\Unit\Model\Order\Shipment\Validator; +namespace Magento\Sales\Test\Unit\Model\Order\Validation; use Magento\Sales\Model\Order; -- GitLab From e0b372ad7c2e41faa58159cd7441b6cec57724f2 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Tue, 16 Aug 2016 18:23:37 +0300 Subject: [PATCH 403/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Model/Order/Shipment/OrderRegistrarInterface.php | 4 ++-- app/code/Magento/Sales/Model/ShipOrder.php | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php index 6131b3585bc..7d54acece35 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/OrderRegistrarInterface.php @@ -19,8 +19,8 @@ interface OrderRegistrarInterface { /** * @param OrderInterface $order - * @param ShipmentInterface $invoice + * @param ShipmentInterface $shipment * @return OrderInterface */ - public function register(OrderInterface $order, ShipmentInterface $invoice); + public function register(OrderInterface $order, ShipmentInterface $shipment); } diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php index a554b83f6b2..a989ee5e865 100644 --- a/app/code/Magento/Sales/Model/ShipOrder.php +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -17,6 +17,7 @@ use Magento\Sales\Model\Order\Shipment\NotifierInterface; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; use Magento\Sales\Model\Order\ShipmentQuantityValidator; use Magento\Sales\Model\Order\Validation\CanShip; +use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface; use Psr\Log\LoggerInterface; /** @@ -75,6 +76,11 @@ class ShipOrder implements ShipOrderInterface */ private $orderValidator; + /** + * @var OrderRegistrarInterface + */ + private $orderRegistrar; + /** * @param ResourceConnection $resourceConnection * @param OrderRepositoryInterface $orderRepository @@ -98,6 +104,7 @@ class ShipOrder implements ShipOrderInterface OrderConfig $config, ShipmentRepositoryInterface $shipmentRepository, NotifierInterface $notifierInterface, + OrderRegistrarInterface $orderRegistrar, LoggerInterface $logger ) { $this->resourceConnection = $resourceConnection; @@ -110,6 +117,7 @@ class ShipOrder implements ShipOrderInterface $this->shipmentRepository = $shipmentRepository; $this->notifierInterface = $notifierInterface; $this->logger = $logger; + $this->orderRegistrar = $orderRegistrar; } /** @@ -166,6 +174,7 @@ class ShipOrder implements ShipOrderInterface } $connection->beginTransaction(); try { + $this->orderRegistrar->register($order, $shipment); $order->setState( $this->orderStateResolver->getStateForOrder($order, [OrderStateResolverInterface::IN_PROGRESS]) ); -- GitLab From 2202002e3562a1baa1a21cddd37b9cfb189e4a3a Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 16 Aug 2016 18:23:43 +0300 Subject: [PATCH 404/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Plugin/CustomerPlugin.php | 67 +++++-------------- .../Unit/Model/Plugin/CustomerPluginTest.php | 47 +++---------- 2 files changed, 29 insertions(+), 85 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index d785b3a82af..dffb3829335 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -30,63 +30,38 @@ class CustomerPlugin /** * Plugin after create customer that updates any newsletter subscription that may have existed. + * If we have extension attribute (is_subscribed) we need to subscribe that customer * * @param CustomerRepository $subject + * @param CustomerInterface $result * @param CustomerInterface $customer * @return CustomerInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterSave(CustomerRepository $subject, CustomerInterface $customer) + public function afterSave(CustomerRepository $subject, CustomerInterface $result, CustomerInterface $customer) { - $this->subscriberFactory->create()->updateSubscription($customer->getId()); - return $customer; - } - - /** - * Plugin around customer repository save. If we have extension attribute (is_subscribed) we need to subscribe that customer - * - * @param CustomerRepository $subject - * @param \Closure $proceed - * @param CustomerInterface $customer - * @param null $passwordHash - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function aroundSave( - CustomerRepository $subject, - \Closure $proceed, - CustomerInterface $customer, - $passwordHash = null - ) { - /** @var CustomerInterface $savedCustomer */ - $savedCustomer = $proceed($customer, $passwordHash); - - if ($savedCustomer->getId() && $customer->getExtensionAttributes()) { + $this->subscriberFactory->create()->updateSubscription($result->getId()); + if ($result->getId() && $customer->getExtensionAttributes()) { if ($customer->getExtensionAttributes()->getIsSubscribed() === true) { - $this->subscriberFactory->create()->subscribeCustomerById($savedCustomer->getId()); + $this->subscriberFactory->create()->subscribeCustomerById($result->getId()); } elseif ($customer->getExtensionAttributes()->getIsSubscribed() === false) { - $this->subscriberFactory->create()->unsubscribeCustomerById($savedCustomer->getId()); + $this->subscriberFactory->create()->unsubscribeCustomerById($result->getId()); } } - - return $savedCustomer; + return $result; } - + /** - * Plugin around delete customer that updates any newsletter subscription that may have existed. + * Plugin after delete customer that updates any newsletter subscription that may have existed. * * @param CustomerRepository $subject - * @param callable $deleteCustomerById Function we are wrapping around - * @param int $customerId Input to the function + * @param bool $result + * @param int $customerId * @return bool */ - public function aroundDeleteById( - CustomerRepository $subject, - callable $deleteCustomerById, - $customerId - ) { + public function afterDeleteById(CustomerRepository $subject, $result, $customerId) + { $customer = $subject->getById($customerId); - $result = $deleteCustomerById($customerId); - /** @var \Magento\Newsletter\Model\Subscriber $subscriber */ $subscriber = $this->subscriberFactory->create(); $subscriber->loadByEmail($customer->getEmail()); if ($subscriber->getId()) { @@ -96,21 +71,15 @@ class CustomerPlugin } /** - * Plugin around delete customer that updates any newsletter subscription that may have existed. + * Plugin after delete customer that updates any newsletter subscription that may have existed. * * @param CustomerRepository $subject - * @param callable $deleteCustomer Function we are wrapping around - * @param CustomerInterface $customer Input to the function + * @param bool $result + * @param CustomerInterface $customer * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDelete( - CustomerRepository $subject, - callable $deleteCustomer, - $customer - ) { - $result = $deleteCustomer($customer); - /** @var \Magento\Newsletter\Model\Subscriber $subscriber */ + public function afterDelete(CustomerRepository $subject, $result, CustomerInterface $customer) { $subscriber = $this->subscriberFactory->create(); $subscriber->loadByEmail($customer->getEmail()); if ($subscriber->getId()) { diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php index b4bc13043bf..bad949adec6 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php @@ -60,26 +60,11 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAfterSave() + public function testAfterSaveWithoutIsSubscribed() { - $customerId = 1; - $subject = $this->getMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); - $customer = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class); - $customer->expects($this->once())->method('getId')->willReturn($customerId); - $this->subscriber->expects($this->once())->method('updateSubscription')->with($customerId)->willReturnSelf(); - - $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer)); - } - - public function testAroundSaveWithoutIsSubscribed() - { - $passwordHash = null; $customerId = 1; /** @var CustomerInterface | \PHPUnit_Framework_MockObject_MockObject $customer */ $customer = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class); - $proceed = function (CustomerInterface $customer, $passwordHash = null) use ($customer) { - return $customer; - }; /** @var CustomerRepository | \PHPUnit_Framework_MockObject_MockObject $subject */ $subject = $this->getMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); @@ -87,26 +72,25 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->method("getId") ->willReturn($customerId); - $this->assertEquals($customer, $this->plugin->aroundSave($subject, $proceed, $customer, $passwordHash)); + $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer, $customer)); } /** * @return array */ - public function provideExtensionAttributeDataForAroundSave() + public function provideExtensionAttributeDataForAfterSave() { return [ - [true, true] , + [true, true], [false, false] ]; } /** - * @dataProvider provideExtensionAttributeDataForAroundSave + * @dataProvider provideExtensionAttributeDataForAfterSave */ - public function testAroundSaveWithIsSubscribed($isSubscribed, $subscribeIsCreated) + public function testAfterSaveWithIsSubscribed($isSubscribed, $subscribeIsCreated) { - $passwordHash = null; $customerId = 1; /** @var CustomerInterface | \PHPUnit_Framework_MockObject_MockObject $customer */ $customer = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class); @@ -134,9 +118,6 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->with($customerId); } - $proceed = function (CustomerInterface $customer, $passwordHash = null) use ($customer) { - return $customer; - }; /** @var CustomerRepository | \PHPUnit_Framework_MockObject_MockObject $subject */ $subject = $this->getMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); @@ -144,14 +125,11 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->method("getId") ->willReturn($customerId); - $this->assertEquals($customer, $this->plugin->aroundSave($subject, $proceed, $customer, $passwordHash)); + $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer, $customer)); } - public function testAroundDelete() + public function testAfterDelete() { - $deleteCustomer = function () { - return true; - }; $subject = $this->getMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $customer = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class); $customer->expects($this->once())->method('getEmail')->willReturn('test@test.com'); @@ -159,15 +137,12 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase $this->subscriber->expects($this->once())->method('getId')->willReturn(1); $this->subscriber->expects($this->once())->method('delete')->willReturnSelf(); - $this->assertEquals(true, $this->plugin->aroundDelete($subject, $deleteCustomer, $customer)); + $this->assertEquals(true, $this->plugin->afterDelete($subject, true, $customer)); } - public function testAroundDeleteById() + public function testAfterDeleteById() { $customerId = 1; - $deleteCustomerById = function () { - return true; - }; $subject = $this->getMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $customer = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class); $subject->expects($this->once())->method('getById')->willReturn($customer); @@ -176,6 +151,6 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase $this->subscriber->expects($this->once())->method('getId')->willReturn(1); $this->subscriber->expects($this->once())->method('delete')->willReturnSelf(); - $this->assertEquals(true, $this->plugin->aroundDeleteById($subject, $deleteCustomerById, $customerId)); + $this->assertEquals(true, $this->plugin->afterDeleteById($subject, true, $customerId)); } } -- GitLab From 2800b5b0a7261acb64c0dbaf12e091337c637ffb Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Tue, 16 Aug 2016 18:25:30 +0300 Subject: [PATCH 405/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Controller/Result/VarnishPlugin.php | 72 ++++----- .../Controller/Result/VarnishPluginTest.php | 150 ++++++++++++------ 2 files changed, 136 insertions(+), 86 deletions(-) diff --git a/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php index 19868a2261f..19337fc566b 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php @@ -5,7 +5,12 @@ */ namespace Magento\PageCache\Model\Controller\Result; +use Magento\PageCache\Model\Config; +use Magento\Framework\App\PageCache\Version; +use Magento\Framework\App\State as AppState; +use Magento\Framework\Registry; use Magento\Framework\App\Response\Http as ResponseHttp; +use Magento\Framework\Controller\ResultInterface; /** * Plugin for processing varnish cache @@ -13,74 +18,59 @@ use Magento\Framework\App\Response\Http as ResponseHttp; class VarnishPlugin { /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var Config */ - protected $config; + private $config; /** - * @var \Magento\Framework\App\PageCache\Version + * @var Version */ - protected $version; + private $version; /** - * @var \Magento\Framework\App\PageCache\Kernel + * @var AppState */ - protected $kernel; + private $state; /** - * @var \Magento\Framework\App\State + * @var Registry */ - protected $state; + private $registry; /** - * @var \Magento\Framework\Registry + * @param Config $config + * @param Version $version + * @param AppState $state + * @param Registry $registry */ - protected $registry; - - /** - * Constructor - * - * @param \Magento\PageCache\Model\Config $config - * @param \Magento\Framework\App\PageCache\Version $version - * @param \Magento\Framework\App\PageCache\Kernel $kernel - * @param \Magento\Framework\App\State $state - * @param \Magento\Framework\Registry $registry - */ - public function __construct( - \Magento\PageCache\Model\Config $config, - \Magento\Framework\App\PageCache\Version $version, - \Magento\Framework\App\PageCache\Kernel $kernel, - \Magento\Framework\App\State $state, - \Magento\Framework\Registry $registry - ) { + public function __construct(Config $config, Version $version, AppState $state, Registry $registry) + { $this->config = $config; $this->version = $version; - $this->kernel = $kernel; $this->state = $state; $this->registry = $registry; } /** - * @param \Magento\Framework\Controller\ResultInterface $subject - * @param callable $proceed + * @param ResultInterface $subject + * @param ResultInterface $result * @param ResponseHttp $response - * @return \Magento\Framework\Controller\ResultInterface + * @return ResultInterface + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundRenderResult( - \Magento\Framework\Controller\ResultInterface $subject, - \Closure $proceed, - ResponseHttp $response - ) { - $proceed($response); + public function afterRenderResult(ResultInterface $subject, ResultInterface $result, ResponseHttp $response) + { $usePlugin = $this->registry->registry('use_page_cache_plugin'); - if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled() - && $usePlugin) { + + if ($this->config->getType() == Config::VARNISH && $this->config->isEnabled() && $usePlugin) { $this->version->process(); - if ($this->state->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { + + if ($this->state->getMode() == AppState::MODE_DEVELOPER) { $response->setHeader('X-Magento-Debug', 1); } } - return $subject; + return $result; } } diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php index e58aae1668f..d280a3d7d8c 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php @@ -5,72 +5,132 @@ */ namespace Magento\PageCache\Test\Unit\Model\Controller\Result; +use Magento\PageCache\Model\Controller\Result\VarnishPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\PageCache\Model\Config; +use Magento\Framework\App\PageCache\Version; +use Magento\Framework\App\State as AppState; +use Magento\Framework\Registry; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\App\Response\Http as ResponseHttp; + class VarnishPluginTest extends \PHPUnit_Framework_TestCase { /** - * @param bool $usePlugin - * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $setCacheDebugHeaderCount - * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $getModeCount - * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $processCount - * @dataProvider dataProvider + * @var VarnishPlugin */ - public function testAroundResult($usePlugin, $setCacheDebugHeaderCount, $getModeCount, $processCount) - { - /** @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject $response */ - $response = $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false); - $response->expects($setCacheDebugHeaderCount)->method('setHeader') - ->with('X-Magento-Debug', 1); + private $plugin; - /** @var \Magento\Framework\Controller\ResultInterface $result */ - $result = $this->getMock(\Magento\Framework\Controller\ResultInterface::class, [], [], '', false); - $closure = function () use ($result) { - return $result; - }; + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; - /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject $registry */ - $registry = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false); - $registry->expects($this->once())->method('registry')->with('use_page_cache_plugin') - ->will($this->returnValue($usePlugin)); + /** + * @var Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; - /** @var \Magento\PageCache\Model\Config|\PHPUnit_Framework_MockObject_MockObject $config */ - $config = $this->getMock(\Magento\PageCache\Model\Config::class, [], [], '', false); - $config->expects($this->once())->method('isEnabled')->will($this->returnValue(true)); - $config->expects($this->once())->method('getType') - ->will($this->returnValue(\Magento\PageCache\Model\Config::VARNISH)); + /** + * @var Version|\PHPUnit_Framework_MockObject_MockObject + */ + private $versionMock; + + /** + * @var AppState|\PHPUnit_Framework_MockObject_MockObject + */ + private $appStateMock; + + /** + * @var Registry|\PHPUnit_Framework_MockObject_MockObject + */ + private $registryMock; - /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject $state */ - $state = $this->getMock(\Magento\Framework\App\State::class, [], [], '', false); - $state->expects($getModeCount)->method('getMode') - ->will($this->returnValue(\Magento\Framework\App\State::MODE_DEVELOPER)); + /** + * @var ResultInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $resultMock; - /** @var \Magento\Framework\Controller\ResultInterface|\PHPUnit_Framework_MockObject_MockObject $subject */ - $subject = $this->getMock(\Magento\Framework\Controller\ResultInterface::class, [], [], '', false); + /** + * @var ResponseHttp|\PHPUnit_Framework_MockObject_MockObject + */ + private $responseMock; - /** @var \Magento\Framework\App\PageCache\Version|\PHPUnit_Framework_MockObject_MockObject $version */ - $version = $this->getMock(\Magento\Framework\App\PageCache\Version::class, [], [], '', false); - $version->expects($processCount)->method('process'); + protected function setUp() + { + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + $this->versionMock = $this->getMockBuilder(Version::class) + ->disableOriginalConstructor() + ->getMock(); + $this->appStateMock = $this->getMockBuilder(AppState::class) + ->disableOriginalConstructor() + ->getMock(); + $this->registryMock = $this->getMockBuilder(Registry::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resultMock = $this->getMockBuilder(ResultInterface::class) + ->getMockForAbstractClass(); + $this->responseMock = $this->getMockBuilder(ResponseHttp::class) + ->disableOriginalConstructor() + ->getMock(); - /** @var \Magento\PageCache\Model\Controller\Result\VarnishPlugin $plugin */ - $plugin = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( - \Magento\PageCache\Model\Controller\Result\VarnishPlugin::class, + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + VarnishPlugin::class, [ - 'registry' => $registry, - 'config' => $config, - 'state' => $state, - 'version' => $version + 'registry' => $this->registryMock, + 'config' => $this->configMock, + 'state' => $this->appStateMock, + 'version' => $this->versionMock ] ); - $this->assertSame($subject, $plugin->aroundRenderResult($subject, $closure, $response)); + } + + /** + * @param bool $usePlugin + * @param int $setCacheDebugHeaderCount + * @param int $getModeCount + * @param int $processCount + * + * @dataProvider afterRenderResultDataProvider + */ + public function testAfterRenderResult($usePlugin, $setCacheDebugHeaderCount, $getModeCount, $processCount) + { + $this->responseMock->expects(static::exactly($setCacheDebugHeaderCount)) + ->method('setHeader') + ->with('X-Magento-Debug', 1); + $this->registryMock->expects(static::once()) + ->method('registry') + ->with('use_page_cache_plugin') + ->willReturn($usePlugin); + $this->configMock->expects(static::once()) + ->method('isEnabled') + ->willReturn(true); + $this->configMock->expects(static::once()) + ->method('getType') + ->willReturn(Config::VARNISH); + $this->appStateMock->expects(static::exactly($getModeCount)) + ->method('getMode') + ->willReturn(AppState::MODE_DEVELOPER); + $this->versionMock->expects(static::exactly($processCount)) + ->method('process'); + + $this->assertSame( + $this->resultMock, + $this->plugin->afterRenderResult($this->resultMock, $this->resultMock, $this->responseMock) + ); } /** * @return array */ - public function dataProvider() + public function afterRenderResultDataProvider() { return [ - [true, $this->once(), $this->once(), $this->once()], - [false, $this->never(), $this->never(), $this->never()] + [true, 1, 1, 1], + [false, 0, 0, 0] ]; } } -- GitLab From 4829621f5f1da481e847d45aaef59759ceea7ea7 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Tue, 16 Aug 2016 18:26:17 +0300 Subject: [PATCH 406/838] MAGETWO-56778: Value for multiple select attribute does not save -- fixes after QA --- app/code/Magento/Eav/Model/Entity/AttributeLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php index e369ded310b..456f041dba5 100644 --- a/app/code/Magento/Eav/Model/Entity/AttributeLoader.php +++ b/app/code/Magento/Eav/Model/Entity/AttributeLoader.php @@ -64,7 +64,7 @@ class AttributeLoader implements AttributeLoaderInterface */ public function loadAllAttributes(AbstractEntity $resource, DataObject $object = null) { - $suffix = $this->getLoadAllAttributesCacheSuffix(); + $suffix = $this->getLoadAllAttributesCacheSuffix($object); $typeCode = $resource->getEntityType()->getEntityTypeCode(); $attributes = $this->cache->getAttributes($typeCode, $suffix); -- GitLab From 96ebc9da6e51e5e65fcd8685fe61dba2a1258edc Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 16 Aug 2016 18:38:13 +0300 Subject: [PATCH 407/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Search/ReaderPlugin.php | 11 ++- .../Unit/Model/Search/ReaderPluginTest.php | 10 +-- .../Model/Category/Plugin/Storage.php | 7 +- .../Model/Category/Plugin/StorageTest.php | 90 +++++++++++++++++++ .../Plugin/Cms/Model/ResourceModel/Page.php | 16 ++-- .../Cms/Model/ResourceModel/PageTest.php | 16 ++-- .../Adminhtml/Product/Builder/Plugin.php | 24 ++--- .../Group/AttributeMapper/Plugin.php | 36 +++++--- .../Plugin/AroundProductRepositorySave.php | 8 +- .../Model/Product/Validator/Plugin.php | 27 ++++-- .../Option/Plugin/ConfigurableProduct.php | 7 +- .../Adminhtml/Product/Builder/PluginTest.php | 12 +-- .../Group/AttributeMapper/PluginTest.php | 78 ++++++++-------- .../AroundProductRepositorySaveTest.php | 19 ++-- .../Model/Product/Validator/PluginTest.php | 46 +++++----- .../Option/Plugin/ConfigurableProductTest.php | 14 ++- .../Customer/Controller/Plugin/Account.php | 31 +++++-- .../Unit/Controller/Plugin/AccountTest.php | 55 +++++++----- 18 files changed, 315 insertions(+), 192 deletions(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php diff --git a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php index 21dd2f62495..307b34c008f 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php +++ b/app/code/Magento/CatalogSearch/Model/Search/ReaderPlugin.php @@ -24,18 +24,17 @@ class ReaderPlugin /** * Merge reader's value with generated * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @param \Magento\Framework\Config\ReaderInterface $subject - * @param \Closure $proceed - * @param string $scope + * @param array $result + * @param string|null $scope * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundRead( + public function afterRead( \Magento\Framework\Config\ReaderInterface $subject, - \Closure $proceed, + array $result, $scope = null ) { - $result = $proceed($scope); $result = array_merge_recursive($result, $this->requestGenerator->generate()); return $result; } diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/ReaderPluginTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/ReaderPluginTest.php index 69644eee902..afae3ccb4f4 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/ReaderPluginTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/ReaderPluginTest.php @@ -29,18 +29,18 @@ class ReaderPluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundRead() + public function testAfterRead() { + $readerConfig = ['test' => 'b', 'd' => 'e']; $this->requestGenerator->expects($this->once()) ->method('generate') ->will($this->returnValue(['test' => 'a'])); - $result = $this->object->aroundRead( + $result = $this->object->afterRead( $this->getMockBuilder(\Magento\Framework\Config\ReaderInterface::class) ->disableOriginalConstructor()->getMock(), - function () { - return ['test' => 'b', 'd' => 'e']; - } + $readerConfig, + null ); $this->assertEquals(['test' => ['b', 'a'], 'd' => 'e'], $result); diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php index 768660e56da..d024a20e032 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php @@ -33,14 +33,13 @@ class Storage /** * @param \Magento\UrlRewrite\Model\StorageInterface $object - * @param callable $proceed - * @param array $urls + * @param void $result + * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundReplace(StorageInterface $object, \Closure $proceed, array $urls) + public function afterReplace(StorageInterface $object, $result, array $urls) { - $proceed($urls); $toSave = []; foreach ($this->filterUrls($urls) as $record) { $metadata = $record->getMetadata(); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php new file mode 100644 index 00000000000..aa46787d009 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php @@ -0,0 +1,90 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\CatalogUrlRewrite\Model\Category\ProductFactory; +use Magento\UrlRewrite\Model\StorageInterface; +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Storage; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use Magento\UrlRewrite\Model\UrlFinderInterface; +use Magento\CatalogUrlRewrite\Model\Category\Product; +use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\Product as ProductResourceModel; + +class StorageTest extends \PHPUnit_Framework_TestCase +{ + /** @var Storage */ + private $model; + + /** @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject */ + private $productFactory; + + /** @var UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $urlFinder; + + /** @var StorageInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $storage; + + /** @var Product|\PHPUnit_Framework_MockObject_MockObject */ + private $product; + + /** @var ProductResourceModel|\PHPUnit_Framework_MockObject_MockObject */ + private $productResourceModel; + + /** @var UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */ + private $urlRewrite; + + protected function setUp() + { + $this->productFactory = $this->getMockBuilder(ProductFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->storage = $this->getMockBuilder(StorageInterface::class) + ->getMockForAbstractClass(); + $this->urlFinder = $this->getMockBuilder(UrlFinderInterface::class) + ->getMockForAbstractClass(); + $this->product = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productResourceModel = $this->getMockBuilder(ProductResourceModel::class) + ->disableOriginalConstructor() + ->getMock(); + $this->urlRewrite = $this->getMockBuilder(UrlRewrite::class) + ->disableOriginalConstructor() + ->setMethods(['getMetadata', 'getEntityType', 'getIsAutogenerated', 'getUrlRewriteId', 'getEntityId']) + ->getMock(); + + $this->model = (new ObjectManager($this))->getObject( + Storage::class, + [ + 'productFactory' => $this->productFactory, + 'urlFinder' => $this->urlFinder + ] + ); + } + + public function testAfterReplace() + { + $this->urlRewrite->expects(static::any())->method('getMetadata')->willReturn(['category_id' => '5']); + $this->urlRewrite->expects(static::once())->method('getEntityTYpe')->willReturn('product'); + $this->urlRewrite->expects(static::once())->method('getIsAutogenerated')->willReturn(1); + $this->urlRewrite->expects(static::once())->method('getUrlRewriteId')->willReturn('4'); + $this->urlRewrite->expects(static::once())->method('getEntityId')->willReturn('2'); + $this->urlRewrite->setData('request_path', 'test'); + $this->urlRewrite->setData('store_id', '1'); + $productUrls = ['targetPath' => $this->urlRewrite]; + + $this->urlFinder->expects(static::once())->method('findAllByData')->willReturn([$this->urlRewrite]); + + $this->productFactory->expects(static::once())->method('create')->willReturn($this->product); + $this->product->expects(static::once())->method('getResource')->willReturn($this->productResourceModel); + $this->productResourceModel->expects(static::once())->method('saveMultiple')->willReturnSelf(); + + $this->model->afterReplace($this->storage, null, $productUrls); + } +} diff --git a/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/ResourceModel/Page.php b/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/ResourceModel/Page.php index 45579f37b0c..c605d3977d9 100644 --- a/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/ResourceModel/Page.php +++ b/app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/ResourceModel/Page.php @@ -9,6 +9,8 @@ use Magento\UrlRewrite\Model\UrlPersistInterface; use Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator; use Magento\CmsUrlRewrite\Model\CmsPageUrlRewriteGenerator; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; /** * Before save and around delete plugin for \Magento\Cms\Model\ResourceModel\Page: @@ -63,18 +65,16 @@ class Page * On delete handler to remove related url rewrites * * @param \Magento\Cms\Model\ResourceModel\Page $subject - * @param \Closure $proceed - * @param \Magento\Framework\Model\AbstractModel $page - * @return \Magento\Cms\Model\ResourceModel\Page - * + * @param AbstractDb $result + * @param AbstractModel $page + * @return AbstractDb * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDelete( + public function afterDelete( \Magento\Cms\Model\ResourceModel\Page $subject, - \Closure $proceed, - \Magento\Framework\Model\AbstractModel $page + AbstractDb $result, + AbstractModel $page ) { - $result = $proceed($page); if ($page->isDeleted()) { $this->urlPersist->deleteByData( [ diff --git a/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php b/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php index 42b1b42469d..832314bd85f 100644 --- a/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php +++ b/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php @@ -83,11 +83,11 @@ class PageTest extends \PHPUnit_Framework_TestCase ] ); - $this->assertEquals( - 'URL Rewrite Result', - $this->pageObject->aroundDelete( + $this->assertSame( + $this->cmsPageResourceMock, + $this->pageObject->afterDelete( + $this->cmsPageResourceMock, $this->cmsPageResourceMock, - $this->closureMock, $this->cmsPageMock ) ); @@ -102,11 +102,11 @@ class PageTest extends \PHPUnit_Framework_TestCase $this->urlPersistMock->expects($this->never()) ->method('deleteByData'); - $this->assertEquals( - 'URL Rewrite Result', - $this->pageObject->aroundDelete( + $this->assertSame( + $this->cmsPageResourceMock, + $this->pageObject->afterDelete( + $this->cmsPageResourceMock, $this->cmsPageResourceMock, - $this->closureMock, $this->cmsPageMock ) ); diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php index ada1488e9cd..609807b707a 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php @@ -8,6 +8,9 @@ namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product\Builder; use Magento\Catalog\Model\ProductFactory; use Magento\ConfigurableProduct\Model\Product\Type; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Controller\Adminhtml\Product\Builder; +use Magento\Framework\App\RequestInterface; class Plugin { @@ -32,21 +35,18 @@ class Plugin } /** - * @param \Magento\Catalog\Controller\Adminhtml\Product\Builder $subject - * @param callable $proceed - * @param \Magento\Framework\App\RequestInterface $request - * - * @return \Magento\Catalog\Model\Product - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @param Builder $subject + * @param Product $product + * @param RequestInterface $request + * @return Product + * SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function aroundBuild( - \Magento\Catalog\Controller\Adminhtml\Product\Builder $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request + public function afterBuild( + Builder $subject, + Product $product, + RequestInterface $request ) { - $product = $proceed($request); - if ($request->has('attributes')) { $attributes = $request->getParam('attributes'); if (!empty($attributes)) { diff --git a/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php index 6f14a13e8e6..77bee2da923 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php @@ -9,6 +9,7 @@ namespace Magento\ConfigurableProduct\Model\Entity\Product\Attribute\Group\Attri use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\AttributeFactory; use Magento\Framework\Registry; +use Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface; class Plugin { @@ -27,6 +28,11 @@ class Plugin */ protected $configurableAttributes; + /** + * @var int|string + */ + private $setId; + /** * @param AttributeFactory $attributeFactory * @param Registry $registry @@ -37,29 +43,39 @@ class Plugin $this->attributeFactory = $attributeFactory; } + /** + * AttributeMapperInterface $subject + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeMap(AttributeMapperInterface $subject) + { + $this->setId = $this->registry->registry('current_attribute_set')->getId(); + } + /** * Add is_configurable field to attribute presentation * - * @param \Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface $subject - * @param callable $proceed + * @param AttributeMapperInterface $subject + * @param array * @param \Magento\Eav\Model\Entity\Attribute $attribute * * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundMap( - \Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface $subject, - \Closure $proceed, + public function afterMap( + AttributeMapperInterface $subject, + array $result, \Magento\Eav\Model\Entity\Attribute $attribute ) { - $setId = $this->registry->registry('current_attribute_set')->getId(); - $result = $proceed($attribute); - if (!isset($this->configurableAttributes[$setId])) { - $this->configurableAttributes[$setId] = $this->attributeFactory->create()->getUsedAttributes($setId); + if (!isset($this->configurableAttributes[$this->setId])) { + $this->configurableAttributes[$this->setId] = $this->attributeFactory->create()->getUsedAttributes( + $this->setId + ); } $result['is_configurable'] = (int)in_array( $attribute->getAttributeId(), - $this->configurableAttributes[$setId] + $this->configurableAttributes[$this->setId] ); return $result; } diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php index be12fc8da29..0165ec8ac02 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php +++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php @@ -43,7 +43,7 @@ class AroundProductRepositorySave /** * @param ProductRepositoryInterface $subject - * @param callable $proceed + * @param ProductInterface $result * @param ProductInterface $product * @param bool $saveOptions * @return ProductInterface @@ -52,14 +52,12 @@ class AroundProductRepositorySave * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundSave( + public function afterSave( ProductRepositoryInterface $subject, - \Closure $proceed, + ProductInterface $result, ProductInterface $product, $saveOptions = false ) { - /** @var ProductInterface $result */ - $result = $proceed($product, $saveOptions); if ($product->getTypeId() !== Configurable::TYPE_CODE) { return $result; } diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php index c0b287214ea..7fc383b466f 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php @@ -47,28 +47,41 @@ class Plugin $this->jsonHelper = $jsonHelper; } + /** + * @param Product\Validator $subject + * @param Product $product + * @param RequestInterface $request + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeValidate( + \Magento\Catalog\Model\Product\Validator $subject, + \Magento\Catalog\Model\Product $product, + \Magento\Framework\App\RequestInterface $request + ) { + if ($request->has('attributes')) { + $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE); + } + } + /** * Validate product data * * @param Product\Validator $subject - * @param Closure $proceed + * @param bool|array $result * @param Product $product * @param RequestInterface $request * @param \Magento\Framework\DataObject $response * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundValidate( + public function afterValidate( \Magento\Catalog\Model\Product\Validator $subject, - Closure $proceed, + $result, \Magento\Catalog\Model\Product $product, \Magento\Framework\App\RequestInterface $request, \Magento\Framework\DataObject $response ) { - if ($request->has('attributes')) { - $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE); - } - $result = $proceed($product, $request, $response); $variationProducts = (array)$request->getPost('variations-matrix'); if ($variationProducts) { $validationResult = $this->_validateProductVariations($product, $variationProducts, $request); diff --git a/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php b/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php index 73e88eb5333..1657fb8aaae 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php +++ b/app/code/Magento/ConfigurableProduct/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProduct.php @@ -13,20 +13,19 @@ class ConfigurableProduct * Initialize stock item for configurable product type * * @param \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option $subject - * @param callable $proceed + * @param \Magento\CatalogInventory\Model\Stock\Item $stockItem * @param \Magento\Quote\Model\Quote\Item\Option $option * @param \Magento\Quote\Model\Quote\Item $quoteItem * * @return \Magento\CatalogInventory\Api\Data\StockItemInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundGetStockItem( + public function afterGetStockItem( \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option $subject, - \Closure $proceed, + \Magento\CatalogInventory\Model\Stock\Item $stockItem, \Magento\Quote\Model\Quote\Item\Option $option, \Magento\Quote\Model\Quote\Item $quoteItem ) { - $stockItem = $proceed($option, $quoteItem); if ($quoteItem->getProductType() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) { $stockItem->setProductName($quoteItem->getName()); } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php index 7056224cffd..80a1bbd4ce6 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php @@ -23,12 +23,12 @@ class PluginTest extends \PHPUnit_Framework_TestCase protected $configurableTypeMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject */ protected $requestMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */ protected $productMock; @@ -48,7 +48,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase protected $frontendAttrMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Controller\Adminhtml\Product\Builder|\PHPUnit_Framework_MockObject_MockObject */ protected $subjectMock; @@ -256,7 +256,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->productMock, - $this->plugin->aroundBuild($this->subjectMock, $this->closureMock, $this->requestMock) + $this->plugin->afterBuild($this->subjectMock, $this->productMock, $this->requestMock) ); } @@ -283,7 +283,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->attributeMock->expects($this->never())->method('getAttributeCode'); $this->assertEquals( $this->productMock, - $this->plugin->aroundBuild($this->subjectMock, $this->closureMock, $this->requestMock) + $this->plugin->afterBuild($this->subjectMock, $this->productMock, $this->requestMock) ); } @@ -299,7 +299,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->attributeMock->expects($this->never())->method('getAttributeCode'); $this->assertEquals( $this->productMock, - $this->plugin->aroundBuild($this->subjectMock, $this->closureMock, $this->requestMock) + $this->plugin->afterBuild($this->subjectMock, $this->productMock, $this->requestMock) ); } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php index ea49bf0da16..70663f943be 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php @@ -6,6 +6,7 @@ namespace Magento\ConfigurableProduct\Test\Unit\Model\Entity\Product\Attribute\Group\AttributeMapper; use Magento\Eav\Model\Entity\Attribute; +use Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class PluginTest extends \PHPUnit_Framework_TestCase @@ -26,7 +27,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase private $attributeFactory; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var Attribute|\PHPUnit_Framework_MockObject_MockObject */ private $attribute; @@ -35,6 +36,11 @@ class PluginTest extends \PHPUnit_Framework_TestCase */ private $magentoObject; + /** + * @var AttributeMapperInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $attributeMapper; + protected function setUp() { $helper = new ObjectManager($this); @@ -51,62 +57,56 @@ class PluginTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $this->attribute = $this->getMockBuilder( - \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute::class - ) - ->setMethods(['getUsedAttributes', 'getAttributeId', '__wakeup']) + $this->magentoObject = $this->getMockBuilder(\Magento\Framework\DataObject::class) + ->setMethods(['getId']) ->disableOriginalConstructor() ->getMock(); - $this->magentoObject = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->setMethods(['getId']) + $this->attributeMapper = $this->getMockBuilder(AttributeMapperInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->attribute = $this->getMockBuilder(Attribute::class) + ->setMethods(['getUsedAttributes', 'getAttributeId', '__wakeup']) ->disableOriginalConstructor() ->getMock(); $this->model = $helper->getObject( \Magento\ConfigurableProduct\Model\Entity\Product\Attribute\Group\AttributeMapper\Plugin::class, - ['registry' => $this->registry, 'attributeFactory' => $this->attributeFactory] + [ + 'registry' => $this->registry, + 'attributeFactory' => $this->attributeFactory, + 'setId' => '10', + ] ); } - public function testAroundMap() + public function testBeforeMap() { - $attrSetId = 333; - $expected = ['is_configurable' => 1]; + $this->registry->expects(static::once())->method('registry') + ->with('current_attribute_set') + ->willReturn($this->magentoObject); + $this->magentoObject->expects(static::once())->method('getId')->willReturn('10'); - /** @var \PHPUnit_Framework_MockObject_MockObject $attributeMapper */ - $attributeMapper = $this->getMockBuilder( - \Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface::class - ) - ->disableOriginalConstructor() - ->getMock(); - - /** @var \Magento\Eav\Model\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject $attribute */ - $attribute = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class) - ->disableOriginalConstructor() - ->getMock(); - - $proceed = function (Attribute $attribute) { - return []; - }; - - $this->attributeFactory->expects($this->once())->method('create') - ->will($this->returnValue($this->attribute)); + $this->model->beforeMap($this->attributeMapper); + } - $this->attribute->expects($this->once())->method('getUsedAttributes') - ->with($this->equalTo($attrSetId)) - ->will($this->returnValue([$attrSetId])); + public function testAfterMap() + { + $attrSetId = '10'; + $expected = ['is_configurable' => 1]; - $attribute->expects($this->once())->method('getAttributeId') - ->will($this->returnValue($attrSetId)); + $this->attributeFactory->expects(static::once())->method('create') + ->willReturn($this->attribute); - $this->registry->expects($this->once())->method('registry') - ->with($this->equalTo('current_attribute_set')) - ->will($this->returnValue($this->magentoObject)); + $this->attribute->expects(static::once())->method('getUsedAttributes') + ->with($attrSetId) + ->willReturn([$attrSetId]); - $this->magentoObject->expects($this->once())->method('getId')->will($this->returnValue($attrSetId)); + $this->attribute->expects(static::once())->method('getAttributeId') + ->willReturn($attrSetId); - $result = $this->model->aroundMap($attributeMapper, $proceed, $attribute); + $result = $this->model->afterMap($this->attributeMapper, [], $this->attribute); $this->assertEquals($expected, $result); } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php index dee340fca9d..ff50f8174c9 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php @@ -32,11 +32,6 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase */ private $productFactory; - /** - * @var \Closure - */ - private $closure; - /** * @var Product|MockObject */ @@ -91,10 +86,6 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->setMethods(['getExtensionAttributes']) ->getMock(); - $this->closure = function () { - return $this->result; - }; - $this->productRepository = $this->getMockForAbstractClass(ProductRepositoryInterface::class); $this->extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class) @@ -122,7 +113,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->result, - $this->plugin->aroundSave($this->productRepository, $this->closure, $this->product) + $this->plugin->afterSave($this->productRepository, $this->product, $this->product) ); } @@ -148,7 +139,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->result, - $this->plugin->aroundSave($this->productRepository, $this->closure, $this->product) + $this->plugin->afterSave($this->productRepository, $this->product, $this->product) ); } @@ -191,7 +182,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $product->expects(static::never()) ->method('getData'); - $this->plugin->aroundSave($this->productRepository, $this->closure, $this->product); + $this->plugin->afterSave($this->productRepository, $this->product, $this->product); } /** @@ -248,7 +239,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->with($attributeCode) ->willReturn(false); - $this->plugin->aroundSave($this->productRepository, $this->closure, $this->product); + $this->plugin->afterSave($this->productRepository, $this->product, $this->product); } /** @@ -303,6 +294,6 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->with($attributeCode) ->willReturn($attributeId); - $this->plugin->aroundSave($this->productRepository, $this->closure, $this->product); + $this->plugin->afterSave($this->productRepository, $this->product, $this->product); } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php index d66e32aa0e7..d16788e10c4 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php @@ -28,17 +28,17 @@ class PluginTest extends \PHPUnit_Framework_TestCase protected $jsonHelperMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */ protected $productMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject */ protected $requestMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\DataObject|\PHPUnit_Framework_MockObject_MockObject */ protected $responseMock; @@ -53,15 +53,10 @@ class PluginTest extends \PHPUnit_Framework_TestCase protected $proceedResult = [1, 2, 3]; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Catalog\Model\Product\Validator|\PHPUnit_Framework_MockObject_MockObject */ protected $subjectMock; - /** - * @var \Closure - */ - protected $closureMock; - protected function setUp() { $this->eventManagerMock = $this->getMock(\Magento\Framework\Event\Manager::class, [], [], '', false); @@ -82,14 +77,14 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->jsonHelperMock->expects($this->any())->method('jsonDecode')->will($this->returnArgument(0)); $this->productMock = $this->getMock( \Magento\Catalog\Model\Product::class, - ['getData', 'getAttributes'], + ['getData', 'getAttributes', 'setTypeId'], [], '', false ); $this->requestMock = $this->getMock( \Magento\Framework\App\Request\Http::class, - ['getPost', 'getParam', '__wakeup'], + ['getPost', 'getParam', '__wakeup', 'has'], [], '', false @@ -102,10 +97,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase false ); $this->arguments = [$this->productMock, $this->requestMock, $this->responseMock]; - $proceedResult = $this->proceedResult; - $this->closureMock = function () use ($proceedResult) { - return $proceedResult; - }; + $this->subjectMock = $this->getMock(\Magento\Catalog\Model\Product\Validator::class, [], [], '', false); $this->plugin = new \Magento\ConfigurableProduct\Model\Product\Validator\Plugin( $this->eventManagerMock, @@ -114,6 +106,14 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } + public function testBeforeValidate() + { + $this->requestMock->expects(static::once())->method('has')->with('attributes')->willReturn(true); + $this->productMock->expects(static::once())->method('setTypeId')->willReturnSelf(); + + $this->plugin->beforeValidate($this->subjectMock, $this->productMock, $this->requestMock); + } + public function testAroundValidateWithVariationsValid() { $matrix = ['products']; @@ -150,9 +150,9 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->proceedResult, - $plugin->aroundValidate( + $plugin->afterValidate( $this->subjectMock, - $this->closureMock, + $this->proceedResult, $this->productMock, $this->requestMock, $this->responseMock @@ -197,9 +197,9 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->responseMock->expects($this->once())->method('setAttributes')->will($this->returnSelf()); $this->assertEquals( $this->proceedResult, - $plugin->aroundValidate( + $plugin->afterValidate( $this->subjectMock, - $this->closureMock, + $this->proceedResult, $this->productMock, $this->requestMock, $this->responseMock @@ -219,9 +219,9 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->returnValue(null) ); $this->eventManagerMock->expects($this->never())->method('dispatch'); - $this->plugin->aroundValidate( + $this->plugin->afterValidate( $this->subjectMock, - $this->closureMock, + $this->proceedResult, $this->productMock, $this->requestMock, $this->responseMock @@ -313,9 +313,9 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->responseMock->expects($this->never())->method('setError'); - $result = $this->plugin->aroundValidate( + $result = $this->plugin->afterValidate( $this->subjectMock, - $this->closureMock, + $this->proceedResult, $this->productMock, $this->requestMock, $this->responseMock diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php index 7d10cb4511e..2ad52012afc 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php @@ -16,7 +16,7 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase */ public function testAroundGetStockItem(array $data) { - $subjectMock = $this->getMock( + $subjectMock = $this->getMock( \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class, [], [], @@ -24,30 +24,26 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase false ); - $quoteItemMock = $this->getMock( + $quoteItemMock = $this->getMock( \Magento\Quote\Model\Quote\Item::class, ['getProductType', '__wakeup'], [], '', false ); $quoteItemMock->expects($this->once()) ->method('getProductType') ->will($this->returnValue($data['product_type'])); - $stockItemMock = $this->getMock( + $stockItemMock = $this->getMock( \Magento\CatalogInventory\Model\Stock\Item::class, ['setProductName', '__wakeup'], [], '', false ); $matcherMethod = $data['matcher_method']; $stockItemMock->expects($this->$matcherMethod()) ->method('setProductName'); - $optionMock = $this->getMock( + $optionMock = $this->getMock( \Magento\Quote\Model\Quote\Item\Option::class, ['getProduct', '__wakeup'], [], '', false ); - $proceed = function () use ($stockItemMock) { - return $stockItemMock; - }; - $model = new \Magento\ConfigurableProduct\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin\ConfigurableProduct(); - $model->aroundGetStockItem($subjectMock, $proceed, $optionMock, $quoteItemMock, 0); + $model->afterGetStockItem($subjectMock, $stockItemMock, $optionMock, $quoteItemMock, 0); } /** diff --git a/app/code/Magento/Customer/Controller/Plugin/Account.php b/app/code/Magento/Customer/Controller/Plugin/Account.php index 0a19f87b505..b697a381961 100644 --- a/app/code/Magento/Customer/Controller/Plugin/Account.php +++ b/app/code/Magento/Customer/Controller/Plugin/Account.php @@ -8,6 +8,9 @@ namespace Magento\Customer\Controller\Plugin; use Magento\Customer\Model\Session; use Magento\Framework\App\ActionInterface; use Magento\Framework\App\RequestInterface; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Action\AbstractAction; +use Magento\Framework\Controller\ResultInterface; class Account { @@ -34,16 +37,12 @@ class Account } /** - * Dispatch actions allowed for not authorized users - * - * @param ActionInterface $subject - * @param \Closure $proceed + * @param AbstractAction $subject * @param RequestInterface $request - * @return mixed + * @return void */ - public function aroundDispatch( - ActionInterface $subject, - \Closure $proceed, + public function beforeDispatch( + AbstractAction $subject, RequestInterface $request ) { $action = strtolower($request->getActionName()); @@ -56,8 +55,22 @@ class Account } else { $this->session->setNoReferer(true); } + } - $result = $proceed($request); + /** + * Dispatch actions allowed for not authorized users + * + * @param AbstractAction $subject + * @param ResponseInterface|ResultInterface $result + * @param RequestInterface $request + * @return ResponseInterface|ResultInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterDispatch( + AbstractAction $subject, + $result, + RequestInterface $request + ) { $this->session->unsNoReferer(false); return $result; } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php index b175e55f1d3..9bf7febe4e5 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php @@ -9,7 +9,9 @@ use Magento\Customer\Controller\Plugin\Account; use Magento\Customer\Model\Session; use Magento\Framework\App\ActionFlag; use Magento\Framework\App\ActionInterface; +use Magento\Framework\App\Action\AbstractAction; use Magento\Framework\App\Request\Http; +use Magento\Framework\Controller\ResultInterface; class AccountTest extends \PHPUnit_Framework_TestCase { @@ -29,12 +31,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase protected $session; /** - * @var \Closure - */ - protected $proceed; - - /** - * @var ActionInterface | \PHPUnit_Framework_MockObject_MockObject + * @var AbstractAction | \PHPUnit_Framework_MockObject_MockObject */ protected $subject; @@ -48,6 +45,11 @@ class AccountTest extends \PHPUnit_Framework_TestCase */ protected $actionFlag; + /** + * @var ResultInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $resultInterface; + protected function setUp() { $this->session = $this->getMockBuilder(\Magento\Customer\Model\Session::class) @@ -59,16 +61,13 @@ class AccountTest extends \PHPUnit_Framework_TestCase ]) ->getMock(); - $this->subject = $this->getMockBuilder(\Magento\Framework\App\ActionInterface::class) + $this->subject = $this->getMockBuilder(AbstractAction::class) ->setMethods([ 'getActionFlag', ]) + ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->proceed = function () { - return self::EXPECTED_VALUE; - }; - $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) ->disableOriginalConstructor() ->setMethods([ @@ -76,6 +75,10 @@ class AccountTest extends \PHPUnit_Framework_TestCase ]) ->getMock(); + $this->resultInterface = $this->getMockBuilder(ResultInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->actionFlag = $this->getMockBuilder(\Magento\Framework\App\ActionFlag::class) ->disableOriginalConstructor() ->getMock(); @@ -87,9 +90,9 @@ class AccountTest extends \PHPUnit_Framework_TestCase * @param boolean $isActionAllowed * @param boolean $isAuthenticated * - * @dataProvider dataProviderAroundDispatch + * @dataProvider dataProviderBeforeDispatch */ - public function testAroundDispatch( + public function testBeforeDispatch( $action, $allowedActions, $isActionAllowed, @@ -99,11 +102,6 @@ class AccountTest extends \PHPUnit_Framework_TestCase ->method('getActionName') ->willReturn($action); - $this->session->expects($this->once()) - ->method('unsNoReferer') - ->with(false) - ->willReturnSelf(); - if ($isActionAllowed) { $this->session->expects($this->once()) ->method('setNoReferer') @@ -126,13 +124,10 @@ class AccountTest extends \PHPUnit_Framework_TestCase } $plugin = new Account($this->session, $allowedActions); - $this->assertEquals( - self::EXPECTED_VALUE, - $plugin->aroundDispatch($this->subject, $this->proceed, $this->request) - ); + $plugin->beforeDispatch($this->subject, $this->request); } - public function dataProviderAroundDispatch() + public function dataProviderBeforeDispatch() { return [ [ @@ -167,4 +162,18 @@ class AccountTest extends \PHPUnit_Framework_TestCase ], ]; } + + public function testAfterDispatch() + { + $this->session->expects($this->once()) + ->method('unsNoReferer') + ->with(false) + ->willReturnSelf(); + + $plugin = new Account($this->session, ['testaction']); + $this->assertEquals( + $this->resultInterface, + $plugin->afterDispatch($this->subject, $this->resultInterface, $this->request) + ); + } } -- GitLab From b3e9f4772eff32a364558078df9c35482a6ba0e1 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Tue, 16 Aug 2016 18:57:09 +0300 Subject: [PATCH 408/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Magento/Sales/Model/Order/ShipmentQuantityValidator.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index ca17c1d695c..fb3fc9818c1 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -44,6 +44,10 @@ class ShipmentQuantityValidator implements ValidatorInterface if ($entity->getOrderId() === null) { return [__('Order Id is required for shipment document')]; } + + if ($entity->getItems() === null) { + return [__('You can\'t create a shipment without products.')]; + } $messages = []; $order = $this->orderRepository->get($entity->getOrderId()); @@ -64,7 +68,7 @@ class ShipmentQuantityValidator implements ValidatorInterface $messages = []; $orderItem = $this->getOrderItemById($order, $item->getOrderItemId()); if ($orderItem === null) { - return [__('We can not found item "%1".', $item->getOrderItemId())]; + return [__('We can not found item "%1" in order.', $item->getOrderItemId())]; } if ($orderItem->getIsQtyDecimal()) { $qty = (double)$item->getQty(); -- GitLab From 87a1b6aaac85df9d12f2fb973bcce4a36c5e4845 Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 19:38:32 +0300 Subject: [PATCH 409/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- app/code/Magento/Sales/Model/Order/ShipmentFactory.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index dc03ebc191e..efa4a43da45 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -156,21 +156,21 @@ class ShipmentFactory * Adds tracks to the shipment. * * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment - * @param array $tracks + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks * @throws \Magento\Framework\Exception\LocalizedException * @return \Magento\Sales\Api\Data\ShipmentInterface */ protected function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks) { - foreach ($tracks as $data) { - if (empty($data['number'])) { + foreach ($tracks as $track) { + if (!$track->getTrackNumber()) { throw new \Magento\Framework\Exception\LocalizedException( __('Please enter a tracking number.') ); } $shipment->addTrack( - $this->trackFactory->create()->addData($data) + $this->trackFactory->create()->addData($track->getData()) ); } -- GitLab From 234dc9d84f39d123c2e0afc268a8a8eafce829d0 Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 19:44:29 +0300 Subject: [PATCH 410/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Sales/Model/Order/ShipmentFactory.php | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index efa4a43da45..e363f6b47cf 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -6,7 +6,9 @@ namespace Magento\Sales\Model\Order; use Magento\Framework\App\ObjectManager; +use Magento\Framework\EntityManager\HydratorPool; use Magento\Framework\Exception\LocalizedException; +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; /** @@ -41,18 +43,26 @@ class ShipmentFactory private $shipmentValidator; /** - * Factory constructor. + * @var HydratorPool + */ + private $hydratorPool; + + /** + * ShipmentFactory constructor. * * @param \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory - * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + * @param Shipment\TrackFactory $trackFactory + * @param HydratorPool $hydratorPool */ public function __construct( \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory, - \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory, + HydratorPool $hydratorPool ) { $this->converter = $convertOrderFactory->create(); $this->trackFactory = $trackFactory; $this->instanceName = \Magento\Sales\Api\Data\ShipmentInterface::class; + $this->hydratorPool = $hydratorPool; } /** @@ -168,10 +178,8 @@ class ShipmentFactory __('Please enter a tracking number.') ); } - - $shipment->addTrack( - $this->trackFactory->create()->addData($track->getData()) - ); + $hydrator = $this->hydratorPool->getHydrator(ShipmentTrackCreationInterface::class); + $shipment->addTrack($hydrator->extract($track)); } return $shipment; -- GitLab From ab5a67380461be5270df8c20a040da0d56bec64f Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 19:51:32 +0300 Subject: [PATCH 411/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- app/code/Magento/Sales/etc/di.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index daf2a69a619..10e404631e9 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -925,4 +925,11 @@ </argument> </arguments> </type> + <type name="Magento\Framework\EntityManager\HydratorPool"> + <arguments> + <argument name="hydrators" xsi:type="array"> + <item name="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" xsi:type="string">Magento\Framework\EntityManager\HydratorInterface</item> + </argument> + </arguments> + </type> </config> -- GitLab From dc38d66864506e7702185a646b4ec5137e6d394c Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 20:02:43 +0300 Subject: [PATCH 412/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- lib/internal/Magento/Framework/EntityManager/TypeResolver.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/EntityManager/TypeResolver.php b/lib/internal/Magento/Framework/EntityManager/TypeResolver.php index 28e2bdaa709..e40eb50595c 100644 --- a/lib/internal/Magento/Framework/EntityManager/TypeResolver.php +++ b/lib/internal/Magento/Framework/EntityManager/TypeResolver.php @@ -64,7 +64,9 @@ class TypeResolver $this->typeMapping[$className] = $dataInterface; } } - + if (empty($this->typeMapping[$className])) { + $this->typeMapping[$className] = reset($dataInterfaces); + } return $this->typeMapping[$className]; } } -- GitLab From 79e6f0c6ba0da6f4bf8f4e06d6256de6716bc51c Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 20:10:11 +0300 Subject: [PATCH 413/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Magento/Framework/EntityManager/CustomAttributesMapper.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php b/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php index 9147d47f3d9..0d350cc122e 100644 --- a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php +++ b/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php @@ -55,6 +55,9 @@ class CustomAttributesMapper implements MapperInterface */ public function entityToDatabase($entityType, $data) { + if (!$this->metadataPool->hasConfiguration($entityType)) { + return $data; + } $metadata = $this->metadataPool->getMetadata($entityType); if (!$metadata->getEavEntityType()) { return $data; -- GitLab From da2224d692f323f54b37c917dd20446bda7bd2a3 Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 20:25:59 +0300 Subject: [PATCH 414/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Model/Order/ShipmentDocumentFactory.php | 50 +++++++++++++++++-- .../Sales/Model/Order/ShipmentFactory.php | 28 ++++------- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 5a263ea1795..347d9d311de 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -6,6 +6,7 @@ namespace Magento\Sales\Model\Order; +use Magento\Framework\EntityManager\HydratorPool; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; use Magento\Sales\Api\Data\ShipmentCommentInterface; @@ -13,6 +14,7 @@ use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\Data\ShipmentItemCreationInterface; use Magento\Sales\Api\Data\ShipmentPackageInterface; use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; +use Magento\Sales\Model\Order\Shipment\TrackFactory; /** * Class InvoiceDocumentFactory @@ -26,14 +28,31 @@ class ShipmentDocumentFactory */ private $shipmentFactory; + /** + * @var TrackFactory + */ + private $trackFactory; + + /** + * @var HydratorPool + */ + private $hydratorPool; + /** * ShipmentDocumentFactory constructor. + * * @param ShipmentFactory $shipmentFactory + * @param HydratorPool $hydratorPool + * @param TrackFactory $trackFactory */ public function __construct( - ShipmentFactory $shipmentFactory + ShipmentFactory $shipmentFactory, + HydratorPool $hydratorPool, + TrackFactory $trackFactory ) { $this->shipmentFactory = $shipmentFactory; + $this->trackFactory = $trackFactory; + $this->hydratorPool = $hydratorPool; } /** @@ -59,10 +78,9 @@ class ShipmentDocumentFactory /** @var Shipment $shipment */ $shipment = $this->shipmentFactory->create( $order, - $shipmentItems, - $tracks + $shipmentItems ); - + $this->prepareTracks($shipment, $tracks); if ($comment) { $shipment->addComment( $comment->getComment(), @@ -74,6 +92,30 @@ class ShipmentDocumentFactory return $shipment; } + /** + * Adds tracks to the shipment. + * + * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks + * @throws \Magento\Framework\Exception\LocalizedException + * @return \Magento\Sales\Api\Data\ShipmentInterface + */ + private function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks) + { + foreach ($tracks as $track) { + if (!$track->getTrackNumber()) { + throw new \Magento\Framework\Exception\LocalizedException( + __('Please enter a tracking number.') + ); + } + $hydrator = $this->hydratorPool->getHydrator(ShipmentTrackCreationInterface::class); + $shipment->addTrack($this->trackFactory->create($hydrator->extract($track))); + } + + return $shipment; + } + + /** * Convert Items To Array * diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index e363f6b47cf..dc03ebc191e 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -6,9 +6,7 @@ namespace Magento\Sales\Model\Order; use Magento\Framework\App\ObjectManager; -use Magento\Framework\EntityManager\HydratorPool; use Magento\Framework\Exception\LocalizedException; -use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; /** @@ -43,26 +41,18 @@ class ShipmentFactory private $shipmentValidator; /** - * @var HydratorPool - */ - private $hydratorPool; - - /** - * ShipmentFactory constructor. + * Factory constructor. * * @param \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory - * @param Shipment\TrackFactory $trackFactory - * @param HydratorPool $hydratorPool + * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory */ public function __construct( \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory, - \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory, - HydratorPool $hydratorPool + \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory ) { $this->converter = $convertOrderFactory->create(); $this->trackFactory = $trackFactory; $this->instanceName = \Magento\Sales\Api\Data\ShipmentInterface::class; - $this->hydratorPool = $hydratorPool; } /** @@ -166,20 +156,22 @@ class ShipmentFactory * Adds tracks to the shipment. * * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment - * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks + * @param array $tracks * @throws \Magento\Framework\Exception\LocalizedException * @return \Magento\Sales\Api\Data\ShipmentInterface */ protected function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks) { - foreach ($tracks as $track) { - if (!$track->getTrackNumber()) { + foreach ($tracks as $data) { + if (empty($data['number'])) { throw new \Magento\Framework\Exception\LocalizedException( __('Please enter a tracking number.') ); } - $hydrator = $this->hydratorPool->getHydrator(ShipmentTrackCreationInterface::class); - $shipment->addTrack($hydrator->extract($track)); + + $shipment->addTrack( + $this->trackFactory->create()->addData($data) + ); } return $shipment; -- GitLab From 78b53638084215952780a1a0270cf36acba58aed Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Tue, 16 Aug 2016 20:35:17 +0300 Subject: [PATCH 415/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 347d9d311de..18ad880c76f 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -109,9 +109,8 @@ class ShipmentDocumentFactory ); } $hydrator = $this->hydratorPool->getHydrator(ShipmentTrackCreationInterface::class); - $shipment->addTrack($this->trackFactory->create($hydrator->extract($track))); + $shipment->addTrack($this->trackFactory->create(['data' => $hydrator->extract($track)])); } - return $shipment; } -- GitLab From 40f756928fe4a43c5f26fedc562c85ba6a8a9e63 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 16 Aug 2016 20:49:01 +0300 Subject: [PATCH 416/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Product/Quote/Plugin/Initializer.php | 8 +- .../Product/Quote/Plugin/InitializerTest.php | 87 +++++++++++++++++++ 2 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php diff --git a/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php b/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php index f1204efa714..2ab99856df3 100644 --- a/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php +++ b/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php @@ -18,7 +18,7 @@ class Initializer { /** * @param \Magento\Sales\Model\AdminOrder\Product\Quote\Initializer $subject - * @param callable $proceed + * @param \Magento\Quote\Model\Quote\Item|string $item * @param \Magento\Quote\Model\Quote $quote * @param \Magento\Catalog\Model\Product $product * @param \Magento\Framework\DataObject $config @@ -26,15 +26,13 @@ class Initializer * @return \Magento\Quote\Model\Quote\Item|string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundInit( + public function afterInit( \Magento\Sales\Model\AdminOrder\Product\Quote\Initializer $subject, - \Closure $proceed, + $item, \Magento\Quote\Model\Quote $quote, \Magento\Catalog\Model\Product $product, \Magento\Framework\DataObject $config ) { - $item = $proceed($quote, $product, $config); - if (is_string($item) && $product->getTypeId() != Grouped::TYPE_CODE) { $item = $quote->addProduct( $product, diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php new file mode 100644 index 00000000000..3c7c695379c --- /dev/null +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\GroupedProduct\Test\Unit\Model\Sales\AdminOrder\Product\Quote\Plugin; + +use Magento\GroupedProduct\Model\Sales\AdminOrder\Product\Quote\Plugin\Initializer as Model; +use Magento\Sales\Model\AdminOrder\Product\Quote\Initializer; +use Magento\Quote\Model\Quote; +use Magento\Catalog\Model\Product; +use Magento\Quote\Model\Quote\Item; +use Magento\Framework\DataObject; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class InitializerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + /** + * @var Model|\PHPUnit_Framework_MockObject_MockObject + */ + private $model; + + /** + * @var Initializer|\PHPUnit_Framework_MockObject_MockObject + */ + private $initializer; + + /** + * @var Quote|\PHPUnit_Framework_MockObject_MockObject + */ + private $quote; + + /** + * @var Item|\PHPUnit_Framework_MockObject_MockObject + */ + private $quoteItem; + + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ + private $product; + + /** + * @var DataObject|\PHPUnit_Framework_MockObject_MockObject + */ + private $config; + + protected function setUp() + { + $this->objectManagerHelper = new ObjectManagerHelper($this); + + $this->initializer = $this->getMockBuilder(Initializer::class) + ->disableOriginalConstructor() + ->getMock(); + $this->quote = $this->getMockBuilder(Quote::class) + ->setMethods(['addProduct']) + ->disableOriginalConstructor() + ->getMock(); + $this->product = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getTypeId']) + ->getMock(); + $this->quoteItem = $this->getMockBuilder(Item::class) + ->disableOriginalConstructor() + ->getMock(); + $this->config = $this->getMockBuilder(DataObject::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = $this->objectManagerHelper->getObject( + Model::class + ); + } + + public function testAfterInit() + { + $this->assertEquals( + $this->quoteItem, + $this->model->afterInit($this->initializer, $this->quoteItem, $this->quote, $this->product, $this->config) + ); + } +} -- GitLab From 40af627cb749f219b632fa069fa927f9468ec9b2 Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Tue, 16 Aug 2016 14:26:38 -0500 Subject: [PATCH 417/838] MAGETWO-55950: Automate Create new Email Template test - Added New functional test to create new email templates. --- .../Adminhtml/Template/Edit/TemplateForm.php | 21 +++++ .../Adminhtml/Template/Edit/TemplateForm.xml | 9 +++ .../AssertEmailTemplateSuccessSaveMessage.php | 40 ++++++++++ .../Email/Test/Fixture/EmailTemplate.xml | 30 ++++++++ .../Page/Adminhtml/EmailTemplateIndex.xml | 7 ++ .../Test/Page/Adminhtml/EmailTemplateNew.xml | 7 ++ .../CreateEmailTemplateEntityTest.php | 76 +++++++++++++++++++ .../CreateEmailTemplateEntityTest.xml | 10 +++ 8 files changed, 200 insertions(+) create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/Fixture/EmailTemplate.xml create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php create mode 100644 dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php new file mode 100644 index 00000000000..2e55838c84f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php @@ -0,0 +1,21 @@ +<?php + +namespace Magento\Email\Test\Block\Adminhtml\Template\Edit; + +use Magento\Mtf\Block\Form; +use Magento\Mtf\Client\Locator; + +/** + * Synonyms edit form in admin. + */ +/* this class needs to be created becuase we have a customized click on the 'Load' button, its not a standard click +*/ +class TemplateForm extends Form +{ + protected $loadButton = "#load"; + + public function clickLoadTemplate() { + $element = $this->_rootElement->find($this->loadButton, Locator::SELECTOR_CSS); // find this element + $element->click(); // perform the action + } +} \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml new file mode 100644 index 00000000000..80d77ddae1d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml @@ -0,0 +1,9 @@ +<mapping strict="1"> + <fields> + <template_select> + <selector>#template_select</selector> + <input>select</input> + </template_select> + <template_code/> + </fields> +</mapping> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php new file mode 100644 index 00000000000..e1f02d552c1 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php @@ -0,0 +1,40 @@ +<?php + +namespace Magento\Email\Test\Constraint; + +use Magento\Email\Test\Page\Adminhtml\EmailTemplateIndex; +use Magento\Mtf\Constraint\AbstractConstraint; + +/** + * Assertion to check Success Save Message for Email Template. + */ +class AssertEmailTemplateSuccessSaveMessage extends AbstractConstraint +{ + /** + * Check Success Save Message for Email Template. + * + * @param EmailTemplateIndex $emailTemplateIndex + * @return void + */ + public function processAssert(EmailTemplateIndex $emailTemplateIndex) + { + $actualMessage = $emailTemplateIndex->getMessagesBlock()->getSuccessMessage(); + \PHPUnit_Framework_Assert::assertEquals( + self::SUCCESS_MESSAGE, + $actualMessage, + 'Wrong success message is displayed.' + . "\nExpected: " . self::SUCCESS_MESSAGE + . "\nActual: " . $actualMessage + ); + } + + /** + * Text success save message is displayed + * + * @return string + */ + public function toString() + { + return 'Assert that success message is displayed.'; + } +} \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Fixture/EmailTemplate.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Fixture/EmailTemplate.xml new file mode 100644 index 00000000000..92870a5ebab --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Fixture/EmailTemplate.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/fixture.xsd"> + <fixture name="EmailTemplate" + module="Magento_Email" + type="flat" + collection="Magento\Email\Model\ResourceModel\Template\Collection" + repository_class="Magento\Email\Test\Repository\EmailTemplate" + handler_interface="Magento\Email\Test\Handler\EmailTemplate\EmailTemplateInterface" + class="Magento\Email\Test\Fixture\EmailTemplate" + entity_type="email_template"> + <field name="template_select" is_required="1"/> + <field name="template_code" is_required="0"/> + <field name="template_text" is_required="0"/> + <field name="template_styles" is_required="0"/> + <field name="template_type" is_required="0"/> + <field name="template_subject" is_required="0"/> + <field name="template_sender_name" is_required="0"/> + <field name="template_sender_email" is_required="0"/> + <field name="added_at" is_required="0"/> + <field name="modified_at" is_required="0"/> + <field name="orig_template_code" is_required="0"/> + <field name="orig_template_variables" is_required="0"/> + </fixture> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml new file mode 100644 index 00000000000..3e3f33b3b17 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> + <page name="EmailTemplateIndex" area="Adminhtml" mca="admin/email_template/" module="Magento_Email"> + <block name="pageActionsBlock" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector"/> + <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages .messages" strategy="css selector"/> + </page> +</config> diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml new file mode 100644 index 00000000000..c4882c1c565 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> + <page name="EmailTemplateNew" area="Adminhtml" mca="admin/email_template/new/" module="Magento_Email"> + <block name="templateForm" class="Magento\Email\Test\Block\Adminhtml\Template\Edit\TemplateForm" locator="[id='page:main-container']" strategy="css selector" /> + <block name="formPageActions" class="Magento\Backend\Test\Block\FormPageActions" locator=".page-main-actions" strategy="css selector" /> + </page> +</config> \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php new file mode 100644 index 00000000000..0e2359447f2 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php @@ -0,0 +1,76 @@ +<?php + +namespace Magento\Email\Test\TestCase; + +use Magento\Mtf\TestCase\Injectable; +use Magento\Search\Test\Fixture\Synonym; +use Magento\Email\Test\Page\Adminhtml\EmailTemplateIndex; +use Magento\Email\Test\Page\Adminhtml\EmailTemplateNew; +use Magento\Email\Test\Fixture\EmailTemplate; +/** + * Steps: + * 1. Log in to Admin. + * 2. Open the Email Templates page. + * 3. Click the "Add New Template" button. + * 4. Select Email Template. + * 5. Click the "Load Template" button. + * 6. Enter Email Template name. + * 7. Verify the email template saved successfully. + * + * @group Email_(PS) + * @ZephyrId MAGETWO-17155 + */ +class CreateEmailTemplateEntityTest extends Injectable +{ + + /* tags */ + const MVP = 'yes'; + const DOMAIN = 'PS'; + const TEST_TYPE = 'extended_acceptance_test'; + /* end tags */ + + /** + * Email Template Index page. + * + * @var EmailTemplateIndex + */ + private $emailTemplateIndex; + + /** + * New EmailTemplate page. + * + * @var EmailTemplateNew + */ + private $emailTemplateNew; + + /** + * Inject synonym pages. + * + * @param EmailTemplateIndex $EmailTemplateIndex + * @param EmailTemplateNew $EmailTemplateNew + * @return void + */ + public function __inject( + EmailTemplateIndex $EmailTemplateIndex, + EmailTemplateNew $EmailTemplateNew + ) { + $this->emailTemplateIndex = $EmailTemplateIndex; + $this->emailTemplateNew = $EmailTemplateNew; + } + + /** + * Create Email Template test. + * + * @param Synonym $synonym + * @return void + */ + public function test(EmailTemplate $EmailTemplate) + { + $this->emailTemplateIndex->open(); + $this->emailTemplateIndex->getPageActionsBlock()->addNew(); + $this->emailTemplateNew->getTemplateForm()->fill($EmailTemplate); + $this->emailTemplateNew->getTemplateForm()->clickLoadTemplate(); + $this->emailTemplateNew->getFormPageActions()->save(); + sleep(10); + } +} \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml new file mode 100644 index 00000000000..fe7baa16307 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Email\Test\TestCase\CreateEmailTemplateEntityTest" summary="Create Synonyms" ticketId="MAGETWO-123"> + <variation name="CreateEmailTemplateEntityTestVariation1" summary="Create Change Email template"> + <data name="EmailTemplate/data/template_select" xsi:type="string">Change Email</data> + <data name="EmailTemplate/data/template_code" xsi:type="string">Test code_%isolation%</data> + <constraint name="Magento\Email\Test\Constraint\AssertEmailTemplateSuccessSaveMessage" /> + </variation> + </testCase> +</config> \ No newline at end of file -- GitLab From 392925acf4b3ff8914f76472404e73e588dd2b14 Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Tue, 16 Aug 2016 14:37:46 -0500 Subject: [PATCH 418/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - Adding new functional test for verifying admin account sharing option availability. --- .../Test/Block/System/Config/AdminForm.php | 20 +++++++ .../Constraint/AssertAdminAccountSharing.php | 34 +++++++++++ .../Page/Adminhtml/AdminAccountSharing.xml | 6 ++ .../VerifyAdminAccountSharingEntityTest.php | 60 +++++++++++++++++++ .../VerifyAdminAccountSharingEntityTest.xml | 8 +++ 5 files changed, 128 insertions(+) create mode 100644 dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php create mode 100644 dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php create mode 100644 dev/tests/functional/tests/app/Magento/Config/Test/Page/Adminhtml/AdminAccountSharing.xml create mode 100644 dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php create mode 100644 dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php new file mode 100644 index 00000000000..e8c77d23b21 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php @@ -0,0 +1,20 @@ +<?php + +namespace Magento\Config\Test\Block\System\Config; + +use Magento\Mtf\Block\Form; +use Magento\Mtf\Client\Locator; + +/** + * Admin Security edit form in admin. + */ +/* this class needs to be created becuase we need to check for the availability of Admin account sharing settings, This is not possible using the form block class only +*/ +class AdminForm extends Form +{ + protected $AdminAccountSharingField = "#admin_security_admin_account_sharing"; + + public function AdminAccountSharingAvailability() { + return $this->_rootElement->find($this->AdminAccountSharingField, Locator::SELECTOR_CSS)->isVisible(); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php new file mode 100644 index 00000000000..2bc4d1dcbf8 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php @@ -0,0 +1,34 @@ +<?php + +namespace Magento\Config\Test\Constraint; + +use Magento\Mtf\Constraint\AbstractConstraint; +use Magento\Config\Test\Page\Adminhtml\AdminAccountSharing; + +/** + * Assert Admin account sharing is available in Stores>Configuration>advanced>admin grid. + */ +class AssertAdminAccountSharing extends AbstractConstraint +{ + /** + * Assert Admin account sharing is available in Stores>Configuration>advanced>admin grid. + * @param AdminAccountSharing $adminAccountSharing + */ + public function processAssert(AdminAccountSharing $adminAccountSharing) + { + \PHPUnit_Framework_Assert::assertTrue( + $adminAccountSharing->getAdminForm()->AdminAccountSharingAvailability(), + 'Admin Account Sharing Option is not available' + ); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'Admin account sharing is available is present in in Stores>Configuration>advanced>admin grid.'; + } +} \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Page/Adminhtml/AdminAccountSharing.xml b/dev/tests/functional/tests/app/Magento/Config/Test/Page/Adminhtml/AdminAccountSharing.xml new file mode 100644 index 00000000000..0369a7746d5 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Page/Adminhtml/AdminAccountSharing.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> + <page name="AdminAccountSharing" area="Adminhtml" mca="admin/system_config/edit/section/admin/" module="Magento_Config"> + <block name="adminForm" class="Magento\Config\Test\Block\System\Config\AdminForm" locator="[id='page:main-container']" strategy="css selector" /> + </page> + </config> diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php new file mode 100644 index 00000000000..4f64d5a765d --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php @@ -0,0 +1,60 @@ +<?php + +namespace Magento\Config\Test\TestCase; + +use Magento\Mtf\TestCase\Injectable; +use Magento\Config\Test\Page\Adminhtml\AdminAccountSharing; +use Magento\Config\Test\Fixture\ConfigDataWithAdminAccountSharing; + +/** + * Steps: + * 1. Log in to Admin. + * 2. Open the Email Templates page. + * 3. Click the "Add New Template" button. + * 4. Select Email Template. + * 5. Click the "Load Template" button. + * 6. Enter Email Template name. + * 7. Verify the email template saved successfully. + * + * @group Email_(PS) + * @ZephyrId MAGETWO-17155 + */ +class VerifyAdminAccountSharingEntityTest extends Injectable +{ + /* tags */ + const MVP = 'yes'; + const DOMAIN = 'PS'; + const TEST_TYPE = 'extended_acceptance_test'; + /* end tags */ + + /** + * Email Template Index page. + * + * @var AdminAccountSharing + */ + private $adminAccountSharing; + + /** + * Inject synonym pages. + * + * @param $AdminAccountSharing $AdminAccountSharing + * @return void + */ + public function __inject( + AdminAccountSharing $AdminAccountSharing + ) { + $this->adminAccountSharing = $AdminAccountSharing; + } + + /** + * Create Verify Admin Account Sharing test. + * + * @param ConfigDataWithAdminAccountSharing $ConfigDataWithAdminAccountSharing + * @return void + */ + public function test(ConfigDataWithAdminAccountSharing $ConfigDataWithAdminAccountSharing) + { + $this->adminAccountSharing->open(); + + } +} \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml new file mode 100644 index 00000000000..db8ed432f09 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> + <testCase name="Magento\Config\Test\TestCase\VerifyAdminAccountSharingEntityTest" summary="Verify admin account sharing option availability" ticketId="MAGETWO-47822"> + <variation name="VerifyAdminAccountSharingEntityTestVariation1" summary="Verify Admin Account Sharing is available by default"> + <constraint name="Magento\Config\Test\Constraint\AssertAdminAccountSharing" /> + </variation> + </testCase> + </config> \ No newline at end of file -- GitLab From 6b5d77a91ed5497861b283df8ed745fa65a72f2c Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Tue, 16 Aug 2016 17:21:06 -0500 Subject: [PATCH 419/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - Adding new functional test for verifying admin account sharing option availability. --- .../Adminhtml/Template/Edit/TemplateForm.php | 19 ++++++++++------- .../Adminhtml/Template/Edit/TemplateForm.xml | 1 + .../AssertEmailTemplateSuccessSaveMessage.php | 5 ++--- .../Page/Adminhtml/EmailTemplateIndex.xml | 6 ++++++ .../Test/Page/Adminhtml/EmailTemplateNew.xml | 6 ++++++ .../CreateEmailTemplateEntityTest.php | 21 ++++++++++--------- .../CreateEmailTemplateEntityTest.xml | 8 ++++++- 7 files changed, 45 insertions(+), 21 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php index 2e55838c84f..4fcdf35385f 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php @@ -1,21 +1,26 @@ <?php - +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Email\Test\Block\Adminhtml\Template\Edit; use Magento\Mtf\Block\Form; use Magento\Mtf\Client\Locator; /** - * Synonyms edit form in admin. - */ -/* this class needs to be created becuase we have a customized click on the 'Load' button, its not a standard click + Click Load button in Email template form. + this class needs to be created becuase we need a customized click on the 'Load' button, its not a standard click */ class TemplateForm extends Form { - protected $loadButton = "#load"; + private $loadButton = "#load"; + /** + * + */ public function clickLoadTemplate() { - $element = $this->_rootElement->find($this->loadButton, Locator::SELECTOR_CSS); // find this element - $element->click(); // perform the action + $element = $this->_rootElement->find($this->loadButton, Locator::SELECTOR_CSS); // locate the Load button + $element->click(); // click the load button } } \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml index 80d77ddae1d..fe262774647 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <mapping strict="1"> <fields> <template_select> diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php index e1f02d552c1..1f7b25001ff 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php @@ -10,11 +10,10 @@ use Magento\Mtf\Constraint\AbstractConstraint; */ class AssertEmailTemplateSuccessSaveMessage extends AbstractConstraint { + const SUCCESS_MESSAGE = 'You saved the email template.'; + /** - * Check Success Save Message for Email Template. - * * @param EmailTemplateIndex $emailTemplateIndex - * @return void */ public function processAssert(EmailTemplateIndex $emailTemplateIndex) { diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml index 3e3f33b3b17..dbb64d68dcd 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateIndex.xml @@ -1,4 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="EmailTemplateIndex" area="Adminhtml" mca="admin/email_template/" module="Magento_Email"> <block name="pageActionsBlock" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector"/> diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml index c4882c1c565..9c0b1a626e1 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Page/Adminhtml/EmailTemplateNew.xml @@ -1,4 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="EmailTemplateNew" area="Adminhtml" mca="admin/email_template/new/" module="Magento_Email"> <block name="templateForm" class="Magento\Email\Test\Block\Adminhtml\Template\Edit\TemplateForm" locator="[id='page:main-container']" strategy="css selector" /> diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php index 0e2359447f2..e52daf9b6e0 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php @@ -1,12 +1,16 @@ <?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Email\Test\TestCase; use Magento\Mtf\TestCase\Injectable; -use Magento\Search\Test\Fixture\Synonym; use Magento\Email\Test\Page\Adminhtml\EmailTemplateIndex; use Magento\Email\Test\Page\Adminhtml\EmailTemplateNew; use Magento\Email\Test\Fixture\EmailTemplate; + /** * Steps: * 1. Log in to Admin. @@ -15,14 +19,14 @@ use Magento\Email\Test\Fixture\EmailTemplate; * 4. Select Email Template. * 5. Click the "Load Template" button. * 6. Enter Email Template name. - * 7. Verify the email template saved successfully. - * + * 7. Click the "Save" button. + * 8. Verify the email template saved successfully. * @group Email_(PS) * @ZephyrId MAGETWO-17155 */ + class CreateEmailTemplateEntityTest extends Injectable { - /* tags */ const MVP = 'yes'; const DOMAIN = 'PS'; @@ -44,7 +48,7 @@ class CreateEmailTemplateEntityTest extends Injectable private $emailTemplateNew; /** - * Inject synonym pages. + * Inject Email template pages. * * @param EmailTemplateIndex $EmailTemplateIndex * @param EmailTemplateNew $EmailTemplateNew @@ -59,11 +63,9 @@ class CreateEmailTemplateEntityTest extends Injectable } /** - * Create Email Template test. - * - * @param Synonym $synonym - * @return void + * @param EmailTemplate $EmailTemplate */ + public function test(EmailTemplate $EmailTemplate) { $this->emailTemplateIndex->open(); @@ -71,6 +73,5 @@ class CreateEmailTemplateEntityTest extends Injectable $this->emailTemplateNew->getTemplateForm()->fill($EmailTemplate); $this->emailTemplateNew->getTemplateForm()->clickLoadTemplate(); $this->emailTemplateNew->getFormPageActions()->save(); - sleep(10); } } \ No newline at end of file diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml index fe7baa16307..57b95ad4243 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.xml @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> - <testCase name="Magento\Email\Test\TestCase\CreateEmailTemplateEntityTest" summary="Create Synonyms" ticketId="MAGETWO-123"> + <testCase name="Magento\Email\Test\TestCase\CreateEmailTemplateEntityTest" summary="Create new email template" ticketId="MAGETWO-17155"> <variation name="CreateEmailTemplateEntityTestVariation1" summary="Create Change Email template"> <data name="EmailTemplate/data/template_select" xsi:type="string">Change Email</data> <data name="EmailTemplate/data/template_code" xsi:type="string">Test code_%isolation%</data> -- GitLab From 9747bc6f5257a4c1a5e2c68517e381c1218e3464 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 09:39:21 +0300 Subject: [PATCH 420/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Unit/Model/Category/Plugin/Store/GroupTest.php | 11 +++-------- .../Unit/Model/Category/Plugin/Store/ViewTest.php | 3 +++ .../Newsletter/Model/Plugin/CustomerPlugin.php | 3 ++- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php index d22cdabef64..65f65f3f3ce 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php @@ -17,14 +17,9 @@ use Magento\Catalog\Model\Product as Product; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; use Magento\Catalog\Model\ProductFactory; -use Magento\Store\Model\ResourceModel\Store; -use Magento\UrlRewrite\Model\UrlPersistInterface; - -use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; - - - - +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class GroupTest extends \PHPUnit_Framework_TestCase { /** diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php index 8b6658c3fa4..9eb41826f78 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php @@ -18,6 +18,9 @@ use Magento\Catalog\Model\Category; use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; use Magento\Catalog\Model\Product as Product; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class ViewTest extends \PHPUnit_Framework_TestCase { /** diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index dffb3829335..5fa6882ba71 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -79,7 +79,8 @@ class CustomerPlugin * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterDelete(CustomerRepository $subject, $result, CustomerInterface $customer) { + public function afterDelete(CustomerRepository $subject, $result, CustomerInterface $customer) + { $subscriber = $this->subscriberFactory->create(); $subscriber->loadByEmail($customer->getEmail()); if ($subscriber->getId()) { -- GitLab From f60b0059113787a25bd73cf243e2750ebbb50f91 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Wed, 17 Aug 2016 10:16:40 +0300 Subject: [PATCH 421/838] MAGETWO-46317: Support Multiple Updates on the WebSetup --- setup/pub/magento/setup/start-updater.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/pub/magento/setup/start-updater.js b/setup/pub/magento/setup/start-updater.js index ee9bc1e1c0d..5b90c5333cd 100644 --- a/setup/pub/magento/setup/start-updater.js +++ b/setup/pub/magento/setup/start-updater.js @@ -31,7 +31,7 @@ angular.module('start-updater', ['ngStorage']) var payLoad = { 'packages': $scope.packages, 'type': $state.current.type, - 'headerTitle': $scope.title, + 'headerTitle': $scope.packages.size == 1 ? $scope.title : 'Process extensions', 'dataOption': $localStorage.dataOption }; $http.post('index.php/start-updater/update', payLoad) -- GitLab From 238de275e9a7dd796b01bf69ccbb8d4972e0e8fe Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Wed, 17 Aug 2016 10:54:24 +0300 Subject: [PATCH 422/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Sales/Api/Data/ShipmentTrackInterface.php | 45 ++++++++++++ .../Magento/Sales/Api/Data/TrackInterface.php | 46 ------------- .../Model/Order/Shipment/TrackCreation.php | 68 ------------------- 3 files changed, 45 insertions(+), 114 deletions(-) diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php index c5ba339bf02..beafa1370f1 100644 --- a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php @@ -140,6 +140,51 @@ interface ShipmentTrackInterface extends TrackInterface, ExtensibleDataInterface */ public function setParentId($id); + /** + * Sets the weight for the shipment package. + * + * @param float $weight + * @return $this + */ + public function setWeight($weight); + + /** + * Gets the weight for the shipment package. + * + * @return float Weight. + */ + public function getWeight(); + + /** + * Sets the quantity for the shipment package. + * + * @param float $qty + * @return $this + */ + public function setQty($qty); + + /** + * Gets the quantity for the shipment package. + * + * @return float Quantity. + */ + public function getQty(); + + /** + * Sets the description for the shipment package. + * + * @param string $description + * @return $this + */ + public function setDescription($description); + + /** + * Gets the description for the shipment package. + * + * @return string Description. + */ + public function getDescription(); + /** * Retrieve existing extension attributes object or create a new one. * diff --git a/app/code/Magento/Sales/Api/Data/TrackInterface.php b/app/code/Magento/Sales/Api/Data/TrackInterface.php index 075d6b45182..17c08ff9b98 100644 --- a/app/code/Magento/Sales/Api/Data/TrackInterface.php +++ b/app/code/Magento/Sales/Api/Data/TrackInterface.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Sales\Api\Data; /** @@ -13,36 +12,6 @@ namespace Magento\Sales\Api\Data; */ interface TrackInterface { - /** - * Sets the weight for the shipment package. - * - * @param float $weight - * @return $this - */ - public function setWeight($weight); - - /** - * Gets the weight for the shipment package. - * - * @return float Weight. - */ - public function getWeight(); - - /** - * Sets the quantity for the shipment package. - * - * @param float $qty - * @return $this - */ - public function setQty($qty); - - /** - * Gets the quantity for the shipment package. - * - * @return float Quantity. - */ - public function getQty(); - /** * Sets the track number for the shipment package. * @@ -58,21 +27,6 @@ interface TrackInterface */ public function getTrackNumber(); - /** - * Sets the description for the shipment package. - * - * @param string $description - * @return $this - */ - public function setDescription($description); - - /** - * Gets the description for the shipment package. - * - * @return string Description. - */ - public function getDescription(); - /** * Sets the title for the shipment package. * diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index 6c54e0a72c1..d2d7e366e9a 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Sales\Model\Order\Shipment; use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; @@ -13,26 +12,11 @@ use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; */ class TrackCreation implements ShipmentTrackCreationInterface { - /** - * @var float - */ - private $weight; - - /** - * @var float - */ - private $qty; - /** * @var string */ private $trackNumber; - /** - * @var string - */ - private $description; - /** * @var string */ @@ -48,40 +32,6 @@ class TrackCreation implements ShipmentTrackCreationInterface */ private $extensionAttributes; - /** - * {@inheritdoc} - */ - public function getWeight() - { - return $this->weight; - } - - /** - * {@inheritdoc} - */ - public function setWeight($weight) - { - $this->weight = $weight; - return $this; - } - - /** - * {@inheritdoc} - */ - public function getQty() - { - return $this->qty; - } - - /** - * {@inheritdoc} - */ - public function setQty($qty) - { - $this->qty = $qty; - return $this; - } - /** * {@inheritdoc} */ @@ -98,24 +48,6 @@ class TrackCreation implements ShipmentTrackCreationInterface $this->trackNumber = $trackNumber; return $this; } - - /** - * {@inheritdoc} - */ - public function getDescription() - { - return $this->description; - } - - /** - * {@inheritdoc} - */ - public function setDescription($description) - { - $this->description = $description; - return $this; - } - /** * {@inheritdoc} */ -- GitLab From ade4c84c25b7e2d28f490daf8ffb13e99b4fdd98 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 11:11:48 +0300 Subject: [PATCH 423/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/ShipmentFactory.php | 23 --------------- app/code/Magento/Sales/Model/ShipOrder.php | 8 +++--- .../Adminhtml/Order/Shipment/Save.php | 28 ++++++++++++++++++- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index dc03ebc191e..9127bba57a1 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -5,7 +5,6 @@ */ namespace Magento\Sales\Model\Order; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; @@ -140,15 +139,6 @@ class ShipmentFactory $item->setQty($qty); $shipment->addItem($item); } - $errorMessages = $this->getShipmentValidator()->validate( - $shipment, - [ShipmentQuantityValidator::class] - ); - if (!empty($errorMessages)) { - throw new \Magento\Framework\Exception\LocalizedException( - __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages)) - ); - } return $shipment->setTotalQty($totalQty); } @@ -230,17 +220,4 @@ class ShipmentFactory return $item->getQtyToShip() > 0; } } - - /** - * @return ShipmentValidatorInterface - * @deprecated - */ - private function getShipmentValidator() - { - if ($this->shipmentValidator === null) { - $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); - } - - return $this->shipmentValidator; - } } diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php index a989ee5e865..4221676d927 100644 --- a/app/code/Magento/Sales/Model/ShipOrder.php +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -158,13 +158,13 @@ class ShipOrder implements ShipOrderInterface $arguments ); $errorMessages = array_merge( - $this->shipmentValidator->validate( - $shipment, - [ShipmentQuantityValidator::class] - ), $this->orderValidator->validate( $order, [CanShip::class] + ), + $this->shipmentValidator->validate( + $shipment, + [ShipmentQuantityValidator::class] ) ); if (!empty($errorMessages)) { diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index adbd9662464..2626ae0988f 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -7,7 +7,10 @@ namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; +use Magento\Framework\App\ObjectManager; use Magento\Sales\Model\Order\Email\Sender\ShipmentSender; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; +use Magento\Sales\Model\Order\ShipmentQuantityValidator; class Save extends \Magento\Backend\App\Action { @@ -33,6 +36,11 @@ class Save extends \Magento\Backend\App\Action */ protected $shipmentSender; + /** + * @var ShipmentValidatorInterface + */ + private $shipmentValidator; + /** * @param Action\Context $context * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader @@ -119,7 +127,12 @@ class Save extends \Magento\Backend\App\Action $shipment->setCustomerNote($data['comment_text']); $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify'])); } - + $errorMessages = $this->getShipmentValidator()->validate($shipment, [ShipmentQuantityValidator::class]); + if (!empty($errorMessages)) { + throw new \Magento\Sales\Exception\DocumentValidationException( + __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } $shipment->register(); $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email'])); @@ -168,4 +181,17 @@ class Save extends \Magento\Backend\App\Action $this->_redirect('sales/order/view', ['order_id' => $shipment->getOrderId()]); } } + + /** + * @return ShipmentValidatorInterface + * @deprecated + */ + private function getShipmentValidator() + { + if ($this->shipmentValidator === null) { + $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); + } + + return $this->shipmentValidator; + } } -- GitLab From acf39b3a2746006acc8357618ff5d2ff631b6bd2 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Aug 2016 11:14:42 +0300 Subject: [PATCH 424/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage - Fixed code style; --- .../Adminhtml/Product/Builder/Plugin.php | 2 +- .../Attribute/Group/AttributeMapper/Plugin.php | 4 ++-- .../Model/Asset/Plugin/CleanMergedJsCss.php | 6 ++---- .../Model/Asset/Plugin/CleanMergedJsCssTest.php | 15 +++------------ 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php index 609807b707a..a07f2532988 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php @@ -39,7 +39,7 @@ class Plugin * @param Product $product * @param RequestInterface $request * @return Product - * SuppressWarnings(PHPMD.UnusedFormalParameter) + * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function afterBuild( diff --git a/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php index 77bee2da923..77873eaba35 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php @@ -44,7 +44,7 @@ class Plugin } /** - * AttributeMapperInterface $subject + * @param AttributeMapperInterface $subject * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -57,7 +57,7 @@ class Plugin * Add is_configurable field to attribute presentation * * @param AttributeMapperInterface $subject - * @param array + * @param array $result * @param \Magento\Eav\Model\Entity\Attribute $attribute * * @return array diff --git a/app/code/Magento/MediaStorage/Model/Asset/Plugin/CleanMergedJsCss.php b/app/code/Magento/MediaStorage/Model/Asset/Plugin/CleanMergedJsCss.php index 0100c9887f1..4cd6d67a010 100644 --- a/app/code/Magento/MediaStorage/Model/Asset/Plugin/CleanMergedJsCss.php +++ b/app/code/Magento/MediaStorage/Model/Asset/Plugin/CleanMergedJsCss.php @@ -35,15 +35,13 @@ class CleanMergedJsCss * Clean files in database on cleaning merged assets * * @param \Magento\Framework\View\Asset\MergeService $subject - * @param callable $proceed + * @param void $result * * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundCleanMergedJsCss(\Magento\Framework\View\Asset\MergeService $subject, \Closure $proceed) + public function afterCleanMergedJsCss(\Magento\Framework\View\Asset\MergeService $subject, $result) { - $proceed(); - /** @var \Magento\Framework\Filesystem\Directory\ReadInterface $pubStaticDirectory */ $pubStaticDirectory = $this->filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); $mergedDir = $pubStaticDirectory->getAbsolutePath() . '/' diff --git a/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php b/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php index aa6578ebc7e..c60af5f5667 100644 --- a/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php +++ b/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php @@ -22,11 +22,6 @@ class CleanMergedJsCssTest extends \Magento\Framework\TestFramework\Unit\BaseTes */ private $filesystemMock; - /** - * @var bool - */ - private $hasBeenCalled = false; - /** * @var \Magento\MediaStorage\Model\Asset\Plugin\CleanMergedJsCss */ @@ -48,9 +43,7 @@ class CleanMergedJsCssTest extends \Magento\Framework\TestFramework\Unit\BaseTes public function testAroundCleanMergedJsCss() { - $callable = function () { - $this->hasBeenCalled = true; - }; + $this->hasBeenCalled = true; $readDir = 'read directory'; $mergedDir = $readDir . '/' . \Magento\Framework\View\Asset\Merged::getRelativeDir(); @@ -65,11 +58,9 @@ class CleanMergedJsCssTest extends \Magento\Framework\TestFramework\Unit\BaseTes ->with(DirectoryList::STATIC_VIEW) ->willReturn($readDirectoryMock); - $this->model->aroundCleanMergedJsCss( + $this->model->afterCleanMergedJsCss( $this->basicMock(\Magento\Framework\View\Asset\MergeService::class), - $callable + null ); - - $this->assertTrue($this->hasBeenCalled); } } -- GitLab From c9229c2215601080fa2a0cec921ba4b282003aa4 Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Wed, 17 Aug 2016 11:18:40 +0300 Subject: [PATCH 425/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Framework/Interception/Code/InterfaceValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Interception/Code/InterfaceValidator.php b/lib/internal/Magento/Framework/Interception/Code/InterfaceValidator.php index 1ff11552533..93945c607b5 100644 --- a/lib/internal/Magento/Framework/Interception/Code/InterfaceValidator.php +++ b/lib/internal/Magento/Framework/Interception/Code/InterfaceValidator.php @@ -111,13 +111,13 @@ class InterfaceValidator ); break; case self::METHOD_AFTER: - // TODO: Remove this condition check in scope of MAGETWO-56123 if (count($pluginMethodParameters) > 1) { // remove result array_shift($pluginMethodParameters); + $matchedParameters = array_intersect_key($originMethodParameters, $pluginMethodParameters); $this->validateMethodsParameters( $pluginMethodParameters, - $originMethodParameters, + $matchedParameters, $pluginClass, $pluginMethod->getName() ); -- GitLab From 2ea9a2cf2dcc083782bbfee449d9e3ca4e4020b0 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 11:24:02 +0300 Subject: [PATCH 426/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Order/Plugin/Authorization.php | 25 ++--- .../Order/Plugin/AuthorizationTest.php | 91 +++++++++++++++++++ 2 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php index a44a7b78717..401c644b319 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php @@ -20,33 +20,28 @@ class Authorization * @param UserContextInterface $userContext */ public function __construct( - \Magento\Authorization\Model\UserContextInterface $userContext + UserContextInterface $userContext ) { $this->userContext = $userContext; } /** - * Checks if order is allowed - * * @param \Magento\Sales\Model\ResourceModel\Order $subject - * @param callable $proceed + * @param \Magento\Sales\Model\ResourceModel\Order $result * @param \Magento\Framework\Model\AbstractModel $order - * @param mixed $value - * @param null|string $field - * @return \Magento\Sales\Model\Order + * @return \Magento\Sales\Model\ResourceModel\Order * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundLoad( + public function afterLoad( \Magento\Sales\Model\ResourceModel\Order $subject, - \Closure $proceed, - \Magento\Framework\Model\AbstractModel $order, - $value, - $field = null + \Magento\Sales\Model\ResourceModel\Order $result, + \Magento\Framework\Model\AbstractModel $order ) { - $result = $proceed($order, $value, $field); - if (!$this->isAllowed($order)) { - throw NoSuchEntityException::singleField('orderId', $order->getId()); + if ($order instanceof \Magento\Sales\Model\Order) { + if (!$this->isAllowed($order)) { + throw NoSuchEntityException::singleField('orderId', $order->getId()); + } } return $result; } diff --git a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php new file mode 100644 index 00000000000..81fcab88697 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php @@ -0,0 +1,91 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\ResourceModel\Order\Plugin; + +use Magento\Authorization\Model\UserContextInterface; +use Magento\Sales\Model\ResourceModel\Order as ResourceOrder; +use Magento\Sales\Model\Order; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization; + +class AuthorizationTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var UserContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $userContextMock; + + /** + * @var ResourceOrder|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectMock; + + /** + * @var Order|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var Authorization + */ + private $plugin; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->userContextMock = $this->getMockBuilder(UserContextInterface::class) + ->setMethods(['getUserType', 'getUserId']) + ->getMockForAbstractClass(); + $this->subjectMock = $this->getMockBuilder(ResourceOrder::class) + ->disableOriginalConstructor() + ->getMock(); + $this->orderMock = $this->getMockBuilder(Order::class) + ->disableOriginalConstructor() + ->setMethods(['getCustomerId', 'getId']) + ->getMock(); + $this->plugin = $this->objectManager->getObject( + Authorization::class, + ['userContext' => $this->userContextMock] + ); + } + + public function testAfterLoad() + { + $this->userContextMock->expects($this->once()) + ->method('getUserType') + ->willReturn('testType'); + $this->assertEquals( + $this->subjectMock, + $this->plugin->afterLoad($this->subjectMock, $this->subjectMock, $this->orderMock) + ); + } + + /** + * @expectedException \Magento\Framework\Exception\NoSuchEntityException + * @expectedExceptionMessage No such entity with orderId = 1 + */ + public function testAfterLoadWithException() + { + $this->userContextMock->expects($this->once()) + ->method('getUserType') + ->willReturn(UserContextInterface::USER_TYPE_CUSTOMER); + $this->orderMock->expects($this->once()) + ->method('getCustomerId') + ->willReturn(1); + $this->userContextMock->expects($this->once()) + ->method('getUserId') + ->willReturn(2); + $this->orderMock->expects($this->once()) + ->method('getId') + ->willReturn(1); + $this->plugin->afterLoad($this->subjectMock, $this->subjectMock, $this->orderMock); + } +} \ No newline at end of file -- GitLab From 1c8ced92740a6be9a8e13f78d3f315a1cf157361 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 11:29:12 +0300 Subject: [PATCH 427/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Magento/Sales/Model/Order/Shipment/Item.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index 8627f76031b..119639c3522 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -151,7 +151,22 @@ class Item extends AbstractModel implements ShipmentItemInterface */ public function setQty($qty) { - $this->setData('qty', $qty); + if ($this->getOrderItem()->getIsQtyDecimal()) { + $qty = (double)$qty; + } else { + $qty = (int)$qty; + } + $qty = $qty > 0 ? $qty : 0; + /** + * Check qty availability + */ + if ($qty <= $this->getOrderItem()->getQtyToShip() || $this->getOrderItem()->isDummy(true)) { + $this->setData('qty', $qty); + } else { + throw new \Magento\Framework\Exception\LocalizedException( + __('We found an invalid quantity to ship for item "%1".', $this->getName()) + ); + } return $this; } -- GitLab From 9cec3fa638d094394bb8a08338d90d58941924cc Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Wed, 17 Aug 2016 11:35:57 +0300 Subject: [PATCH 428/838] MAGETWO-51169: Last Wizard step Button has incorrect label --- .../Ui/view/base/web/js/lib/step-wizard.js | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js b/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js index e598b5f567a..ace6f2255da 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js @@ -9,7 +9,8 @@ define([ 'jquery', 'underscore', 'ko', - 'mage/backend/notification' + 'mage/backend/notification', + 'mage/translate' ], function (uiRegistry, Component, $, _, ko) { 'use strict'; @@ -28,24 +29,13 @@ define([ this.steps = steps; this.index = 0; this.data = {}; - this.nextLabelText = 'Next'; - this.prevLabelText = 'Back'; - this.initSelectors = function (modalClass) { - var elementSelector = '[data-role=steps-wizard-main]'; - - this.nextLabel = '[data-role="step-wizard-next"]'; - this.prevLabel = '[data-role="step-wizard-prev"]'; - - if (modalClass) { - this.nextLabel = '.' + modalClass + ' ' + this.nextLabel; - this.prevLabel = '.' + modalClass + ' ' + this.prevLabel; - elementSelector = '.' + modalClass + elementSelector; - } - - this.element = $(elementSelector); - $(this.element).notification(); - }; - this.initSelectors(modalClass); + this.nextLabelText = $.mage.__('Next'); + this.prevLabelText = $.mage.__('Back'); + this.elementSelector = '[data-role=steps-wizard-main]'; + this.element = modalClass ? $('.' + modalClass + this.elementSelector) : $(this.elementSelector); + this.nextLabel = '[data-role="step-wizard-next"]'; + this.prevLabel = '[data-role="step-wizard-prev"]'; + this.element.notification(); this.move = function (newIndex) { if (!this.preventSwitch(newIndex)) { if (newIndex > this.index) { -- GitLab From 32d9799e6444227d33e534a3d9b356f4f9ee3e0e Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 11:38:54 +0300 Subject: [PATCH 429/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/Shipment/Item.php | 17 +------------- .../Sales/Model/Order/ShipmentFactory.php | 23 +++++++++++++++++++ .../Adminhtml/Order/Shipment/Save.php | 6 ----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php index 119639c3522..8627f76031b 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php @@ -151,22 +151,7 @@ class Item extends AbstractModel implements ShipmentItemInterface */ public function setQty($qty) { - if ($this->getOrderItem()->getIsQtyDecimal()) { - $qty = (double)$qty; - } else { - $qty = (int)$qty; - } - $qty = $qty > 0 ? $qty : 0; - /** - * Check qty availability - */ - if ($qty <= $this->getOrderItem()->getQtyToShip() || $this->getOrderItem()->isDummy(true)) { - $this->setData('qty', $qty); - } else { - throw new \Magento\Framework\Exception\LocalizedException( - __('We found an invalid quantity to ship for item "%1".', $this->getName()) - ); - } + $this->setData('qty', $qty); return $this; } diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 9127bba57a1..09e03fcaf55 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model\Order; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; @@ -139,6 +140,15 @@ class ShipmentFactory $item->setQty($qty); $shipment->addItem($item); } + $errorMessages = $this->getShipmentValidator()->validate( + $shipment, + [ShipmentQuantityValidator::class] + ); + if (!empty($errorMessages)) { + throw new \Magento\Framework\Exception\LocalizedException( + __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } return $shipment->setTotalQty($totalQty); } @@ -220,4 +230,17 @@ class ShipmentFactory return $item->getQtyToShip() > 0; } } + + /** + * @return ShipmentValidatorInterface + * @deprecated + */ + private function getShipmentValidator() + { + if ($this->shipmentValidator === null) { + $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); + } + + return $this->shipmentValidator; + } } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index 2626ae0988f..6898ade5a77 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -127,12 +127,6 @@ class Save extends \Magento\Backend\App\Action $shipment->setCustomerNote($data['comment_text']); $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify'])); } - $errorMessages = $this->getShipmentValidator()->validate($shipment, [ShipmentQuantityValidator::class]); - if (!empty($errorMessages)) { - throw new \Magento\Sales\Exception\DocumentValidationException( - __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) - ); - } $shipment->register(); $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email'])); -- GitLab From 0ed35d3dac7703393c275b8f6a9009fcdaddf8b3 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 11:47:35 +0300 Subject: [PATCH 430/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/ShipmentFactory.php | 23 -------------- .../Adminhtml/Order/ShipmentLoader.php | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 09e03fcaf55..9127bba57a1 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -5,7 +5,6 @@ */ namespace Magento\Sales\Model\Order; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; @@ -140,15 +139,6 @@ class ShipmentFactory $item->setQty($qty); $shipment->addItem($item); } - $errorMessages = $this->getShipmentValidator()->validate( - $shipment, - [ShipmentQuantityValidator::class] - ); - if (!empty($errorMessages)) { - throw new \Magento\Framework\Exception\LocalizedException( - __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) - ); - } return $shipment->setTotalQty($totalQty); } @@ -230,17 +220,4 @@ class ShipmentFactory return $item->getQtyToShip() > 0; } } - - /** - * @return ShipmentValidatorInterface - * @deprecated - */ - private function getShipmentValidator() - { - if ($this->shipmentValidator === null) { - $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); - } - - return $this->shipmentValidator; - } } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index b452c88887c..2c49937edf7 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -6,7 +6,10 @@ */ namespace Magento\Shipping\Controller\Adminhtml\Order; +use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; +use Magento\Sales\Model\Order\ShipmentQuantityValidator; /** * Class ShipmentLoader @@ -53,6 +56,11 @@ class ShipmentLoader extends DataObject */ protected $orderRepository; + /** + * @var ShipmentValidatorInterface + */ + private $shipmentValidator; + /** * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param \Magento\Framework\Registry $registry @@ -135,9 +143,31 @@ class ShipmentLoader extends DataObject $this->getItemQtys(), $this->getTracking() ); + $errorMessages = $this->getShipmentValidator()->validate( + $shipment, + [ShipmentQuantityValidator::class] + ); + if (!empty($errorMessages)) { + throw new \Magento\Framework\Exception\LocalizedException( + __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } } $this->registry->register('current_shipment', $shipment); return $shipment; } + + /** + * @return ShipmentValidatorInterface + * @deprecated + */ + private function getShipmentValidator() + { + if ($this->shipmentValidator === null) { + $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); + } + + return $this->shipmentValidator; + } } -- GitLab From a18c342cc9096b36b1403e55904bf303b23b1822 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Wed, 17 Aug 2016 12:01:39 +0300 Subject: [PATCH 431/838] MAGETWO-54677: Unit tests fixed --- .../Order/ShipmentDocumentFactoryTest.php | 81 +++++++++++++++++-- .../Unit/Model/Order/ShipmentFactoryTest.php | 2 - 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php index 4d3bad7a377..93f6b7408d6 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -5,12 +5,17 @@ */ namespace Magento\Sales\Test\Unit\Model\Order; +use Magento\Framework\EntityManager\HydratorPool; use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; use Magento\Sales\Api\Data\ShipmentItemCreationInterface; +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; use Magento\Sales\Model\Order\ShipmentFactory; use Magento\Sales\Model\Order\ShipmentDocumentFactory; use Magento\Sales\Model\Order; use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Model\Order\Shipment\TrackFactory; +use Magento\Sales\Model\Order\Shipment\Track; +use Magento\Framework\EntityManager\HydratorInterface; /** * Class InvoiceDocumentFactoryTest @@ -47,6 +52,26 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase */ private $invoiceDocumentFactory; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|HydratorPool + */ + private $hydratorPoolMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|TrackFactory + */ + private $trackFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|TrackFactory + */ + private $hydratorMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|HydratorInterface + */ + private $trackMock; + protected function setUp() { $this->shipmentFactoryMock = $this->getMockBuilder(ShipmentFactory::class) @@ -67,15 +92,39 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class) ->disableOriginalConstructor() - ->setMethods(['addComment']) + ->setMethods(['addComment', 'addTrack']) ->getMockForAbstractClass(); - $this->invoiceDocumentFactory = new ShipmentDocumentFactory($this->shipmentFactoryMock); + $this->hydratorPoolMock = $this->getMockBuilder(HydratorPool::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->trackFactoryMock = $this->getMockBuilder(TrackFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + + $this->trackMock = $this->getMockBuilder(Track::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->hydratorMock = $this->getMockBuilder(HydratorInterface::class) + ->disableOriginalConstructor() + ->setMethods(['extract']) + ->getMockForAbstractClass(); + + $this->invoiceDocumentFactory = new ShipmentDocumentFactory( + $this->shipmentFactoryMock, + $this->hydratorPoolMock, + $this->trackFactoryMock + ); } public function testCreate() { - $tracks = ["1234567890"]; + $trackNum = "123456789"; + $trackData = [$trackNum]; + $tracks = [$this->trackMock]; $appendComment = true; $packages = []; $items = [1 => 10]; @@ -92,11 +141,33 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase ->method('create') ->with( $this->orderMock, - $items, - $tracks + $items ) ->willReturn($this->shipmentMock); + $this->trackMock->expects($this->once()) + ->method('getTrackNumber') + ->willReturn($trackNum); + + $this->shipmentMock->expects($this->once()) + ->method('addTrack') + ->willReturnSelf(); + + $this->hydratorPoolMock->expects($this->once()) + ->method('getHydrator') + ->with(ShipmentTrackCreationInterface::class) + ->willReturn($this->hydratorMock); + + $this->hydratorMock->expects($this->once()) + ->method('extract') + ->with($this->trackMock) + ->willReturn($trackData); + + $this->trackFactoryMock->expects($this->once()) + ->method('create') + ->with(['data' => $trackData]) + ->willReturn($this->trackMock); + if ($appendComment) { $comment = "New comment!"; $visibleOnFront = true; diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php index 3c1ed06f9b9..cbf637f1248 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php @@ -194,8 +194,6 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase } } - $this->shipmentValidatorMock->expects($this->once())->method('validate')->willReturn([]); - $this->assertEquals($shipment, $this->subject->create($order, ['1' => 5], $tracks)); } -- GitLab From 4b0195b1bed3f7558bf01257be3b2833cc4c4015 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Wed, 17 Aug 2016 12:37:28 +0300 Subject: [PATCH 432/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Controller/Result/BuiltinPlugin.php | 76 +++--- .../Model/Controller/Result/VarnishPlugin.php | 2 + .../Controller/Result/BuiltinPluginTest.php | 229 +++++++++++------- 3 files changed, 182 insertions(+), 125 deletions(-) diff --git a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php index 0fcad45130d..d4ce523da0a 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php @@ -5,7 +5,14 @@ */ namespace Magento\PageCache\Model\Controller\Result; +use Magento\PageCache\Model\Config; +use Magento\Framework\App\PageCache\Kernel; +use Magento\Framework\App\State as AppState; +use Magento\Framework\Registry; +use Magento\Framework\Controller\ResultInterface; use Magento\Framework\App\Response\Http as ResponseHttp; +use Zend\Http\Header\HeaderInterface as HttpHeaderInterface; +use Magento\PageCache\Model\Cache\Type as CacheType; /** * Plugin for processing builtin cache @@ -13,39 +20,33 @@ use Magento\Framework\App\Response\Http as ResponseHttp; class BuiltinPlugin { /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var Config */ - protected $config; + private $config; /** - * @var \Magento\Framework\App\PageCache\Kernel + * @var Kernel */ - protected $kernel; + private $kernel; /** - * @var \Magento\Framework\App\State + * @var AppState */ - protected $state; + private $state; /** - * @var \Magento\Framework\Registry + * @var Registry */ - protected $registry; + private $registry; /** - * Constructor - * - * @param \Magento\PageCache\Model\Config $config - * @param \Magento\Framework\App\PageCache\Kernel $kernel - * @param \Magento\Framework\App\State $state - * @param \Magento\Framework\Registry $registry + * @param Config $config + * @param Kernel $kernel + * @param AppState $state + * @param Registry $registry */ - public function __construct( - \Magento\PageCache\Model\Config $config, - \Magento\Framework\App\PageCache\Kernel $kernel, - \Magento\Framework\App\State $state, - \Magento\Framework\Registry $registry - ) { + public function __construct(Config $config, Kernel $kernel, AppState $state, Registry $registry) + { $this->config = $config; $this->kernel = $kernel; $this->state = $state; @@ -53,43 +54,46 @@ class BuiltinPlugin } /** - * @param \Magento\Framework\Controller\ResultInterface $subject - * @param callable $proceed + * Perform result postprocessing + * + * @param ResultInterface $subject + * @param ResultInterface $result * @param ResponseHttp $response - * @return \Magento\Framework\Controller\ResultInterface + * @return ResultInterface + * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundRenderResult( - \Magento\Framework\Controller\ResultInterface $subject, - \Closure $proceed, - ResponseHttp $response - ) { - $result = $proceed($response); + public function afterRenderResult(ResultInterface $subject, ResultInterface $result, ResponseHttp $response) + { $usePlugin = $this->registry->registry('use_page_cache_plugin'); - if (!$usePlugin || !$this->config->isEnabled() - || $this->config->getType() != \Magento\PageCache\Model\Config::BUILT_IN - ) { + + if (!$usePlugin || !$this->config->isEnabled() || $this->config->getType() != Config::BUILT_IN) + { return $result; } - if ($this->state->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { + if ($this->state->getMode() == AppState::MODE_DEVELOPER) { $cacheControlHeader = $response->getHeader('Cache-Control'); - if ($cacheControlHeader instanceof \Zend\Http\Header\HeaderInterface) { + + if ($cacheControlHeader instanceof HttpHeaderInterface) { $response->setHeader('X-Magento-Cache-Control', $cacheControlHeader->getFieldValue()); } + $response->setHeader('X-Magento-Cache-Debug', 'MISS', true); } $tagsHeader = $response->getHeader('X-Magento-Tags'); $tags = []; + if ($tagsHeader) { $tags = explode(',', $tagsHeader->getFieldValue()); $response->clearHeader('X-Magento-Tags'); } - $tags = array_unique(array_merge($tags, [\Magento\PageCache\Model\Cache\Type::CACHE_TAG])); - $response->setHeader('X-Magento-Tags', implode(',', $tags)); + $tags = array_unique(array_merge($tags, [CacheType::CACHE_TAG])); + $response->setHeader('X-Magento-Tags', implode(',', $tags)); $this->kernel->process($response); + return $result; } } diff --git a/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php index 19337fc566b..368a6db80c7 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/VarnishPlugin.php @@ -52,6 +52,8 @@ class VarnishPlugin } /** + * Perform result postprocessing + * * @param ResultInterface $subject * @param ResultInterface $result * @param ResponseHttp $response diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php index 15934f3104b..d735484844f 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php @@ -3,141 +3,192 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\PageCache\Test\Unit\Model\Controller\Result; +use Magento\PageCache\Model\Controller\Result\BuiltinPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\PageCache\Model\Config; +use Magento\Framework\App\PageCache\Kernel; +use Magento\Framework\App\State as AppState; +use Magento\Framework\Registry; +use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\App\Response\Http as ResponseHttp; +use Zend\Http\Header\HeaderInterface as HttpHeaderInterface; +use Magento\PageCache\Model\Cache\Type as CacheType; + class BuiltinPluginTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\PageCache\Model\Controller\Result\BuiltinPlugin + * @var BuiltinPlugin + */ + private $plugin; + + /** + * @var ObjectManagerHelper */ - protected $plugin; + private $objectManagerHelper; /** - * @var \Magento\Framework\Controller\ResultInterface + * @var Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $subject; + private $configMock; /** - * @var \Closure + * @var Kernel|\PHPUnit_Framework_MockObject_MockObject */ - protected $closure; + private $kernelMock; /** - * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject + * @var AppState|\PHPUnit_Framework_MockObject_MockObject */ - protected $response; + private $stateMock; /** - * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject + * @var Registry|\PHPUnit_Framework_MockObject_MockObject */ - protected $registry; + private $registryMock; /** - * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject + * @var ResultInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $state; + private $resultMock; /** - * @var \Zend\Http\Header\HeaderInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResponseHttp|\PHPUnit_Framework_MockObject_MockObject */ - protected $header; + private $responseMock; /** - * @var \Magento\Framework\App\PageCache\Kernel|\PHPUnit_Framework_MockObject_MockObject + * @var HttpHeaderInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $kernel; + private $httpHeaderMock; protected function setUp() { - $result = $this->getMock(\Magento\Framework\Controller\ResultInterface::class, [], [], '', false); - $this->closure = function() use ($result) { - return $result; - }; - - $this->header = $this->getMock(\Zend\Http\Header\HeaderInterface::class, [], [], '', false); - $this->subject = $this->getMock(\Magento\Framework\Controller\ResultInterface::class, [], [], '', false); - $this->response = $this->getMock( - \Magento\Framework\App\Response\Http::class, - ['getHeader', 'clearHeader', 'setHeader'], - [], - '', - false - ); - $this->response->expects($this->any())->method('getHeader')->willReturnMap( + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + $this->kernelMock = $this->getMockBuilder(Kernel::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stateMock = $this->getMockBuilder(AppState::class) + ->disableOriginalConstructor() + ->getMock(); + $this->registryMock = $this->getMockBuilder(Registry::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resultMock = $this->getMockBuilder(ResultInterface::class) + ->getMockForAbstractClass(); + $this->responseMock = $this->getMockBuilder(ResponseHttp::class) + ->disableOriginalConstructor() + ->getMock(); + $this->httpHeaderMock = $this->getMockBuilder(HttpHeaderInterface::class) + ->getMockForAbstractClass(); + + $this->responseMock->expects(static::any()) + ->method('getHeader') + ->willReturnMap( + [ + ['X-Magento-Tags', $this->httpHeaderMock], + ['Cache-Control', $this->httpHeaderMock] + ] + ); + $this->configMock->expects(static::any()) + ->method('isEnabled') + ->willReturn(true); + $this->configMock->expects(static::any()) + ->method('getType') + ->willReturn(Config::BUILT_IN); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + BuiltinPlugin::class, [ - ['X-Magento-Tags', $this->header], - ['Cache-Control', $this->header] - ] - ); - - $this->registry = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false); - - $config = $this->getMock(\Magento\PageCache\Model\Config::class, ['isEnabled', 'getType'], [], '', false); - $config->expects($this->any())->method('isEnabled')->willReturn(true); - $config->expects($this->any())->method('getType')->willReturn(\Magento\PageCache\Model\Config::BUILT_IN); - - $this->kernel = $this->getMock(\Magento\Framework\App\PageCache\Kernel::class, [], [], '', false); - - $this->state = $this->getMock(\Magento\Framework\App\State::class, [], [], '', false); - $this->plugin = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( - \Magento\PageCache\Model\Controller\Result\BuiltinPlugin::class, - [ - 'registry' => $this->registry, - 'config' => $config, - 'kernel' => $this->kernel, - 'state' => $this->state + 'registry' => $this->registryMock, + 'config' => $this->configMock, + 'kernel' => $this->kernelMock, + 'state' => $this->stateMock ] ); } - public function testAroundResultWithoutPlugin() + public function testAfterResultWithoutPlugin() { - $this->registry->expects($this->once())->method('registry')->with('use_page_cache_plugin')->willReturn(false); - $this->kernel->expects($this->never())->method('process')->with($this->response); + $this->registryMock->expects(static::once()) + ->method('registry') + ->with('use_page_cache_plugin') + ->willReturn(false); + $this->kernelMock->expects(static::never()) + ->method('process') + ->with($this->responseMock); + $this->assertSame( - call_user_func($this->closure), - $this->plugin->aroundRenderResult($this->subject, $this->closure, $this->response) + $this->resultMock, + $this->plugin->afterRenderResult($this->resultMock, $this->resultMock, $this->responseMock) ); } - public function testAroundResultWithPlugin() + public function testAfterResultWithPlugin() { - $this->registry->expects($this->once())->method('registry')->with('use_page_cache_plugin')->willReturn(true); - $this->state->expects($this->once())->method('getMode')->willReturn(null); - $this->header->expects($this->any())->method('getFieldValue')->willReturn('tag,tag'); - $this->response->expects($this->once())->method('clearHeader')->with('X-Magento-Tags'); - $this->response->expects($this->once())->method('setHeader')->with( - 'X-Magento-Tags', - 'tag,' . \Magento\PageCache\Model\Cache\Type::CACHE_TAG + $this->registryMock->expects(static::once()) + ->method('registry') + ->with('use_page_cache_plugin') + ->willReturn(true); + $this->stateMock->expects(static::once()) + ->method('getMode') + ->willReturn(null); + $this->httpHeaderMock->expects(static::any()) + ->method('getFieldValue') + ->willReturn('tag,tag'); + $this->responseMock->expects(static::once()) + ->method('clearHeader') + ->with('X-Magento-Tags'); + $this->responseMock->expects(static::once()) + ->method('setHeader') + ->with('X-Magento-Tags', 'tag,' . CacheType::CACHE_TAG); + $this->kernelMock->expects(static::once()) + ->method('process') + ->with($this->responseMock); + + $this->assertSame( + $this->resultMock, + $this->plugin->afterRenderResult($this->resultMock, $this->resultMock, $this->responseMock) ); - $this->kernel->expects($this->once())->method('process')->with($this->response); - $result = call_user_func($this->closure); - $this->assertSame($result, $this->plugin->aroundRenderResult($this->subject, $this->closure, $this->response)); } - public function testAroundResultWithPluginDeveloperMode() + public function testAfterResultWithPluginDeveloperMode() { - $this->registry->expects($this->once())->method('registry')->with('use_page_cache_plugin')->willReturn(true); - $this->state->expects($this->once())->method('getMode') - ->willReturn(\Magento\Framework\App\State::MODE_DEVELOPER); - - $this->header->expects($this->any())->method('getFieldValue')->willReturnOnConsecutiveCalls('test', 'tag,tag2'); + $this->registryMock->expects(static::once()) + ->method('registry') + ->with('use_page_cache_plugin') + ->willReturn(true); + $this->stateMock->expects(static::once()) + ->method('getMode') + ->willReturn(AppState::MODE_DEVELOPER); + $this->httpHeaderMock->expects(static::any()) + ->method('getFieldValue') + ->willReturnOnConsecutiveCalls('test', 'tag,tag2'); + $this->responseMock->expects(static::any()) + ->method('setHeader') + ->withConsecutive( + ['X-Magento-Cache-Control', 'test'], + ['X-Magento-Cache-Debug', 'MISS', true], + ['X-Magento-Tags', 'tag,tag2,' . CacheType::CACHE_TAG] + ); + $this->responseMock->expects(static::once()) + ->method('clearHeader') + ->with('X-Magento-Tags'); + $this->registryMock->expects(static::once()) + ->method('registry') + ->with('use_page_cache_plugin') + ->willReturn(true); + $this->kernelMock->expects(static::once()) + ->method('process') + ->with($this->responseMock); - $this->response->expects($this->any())->method('setHeader')->withConsecutive( - ['X-Magento-Cache-Control', 'test'], - ['X-Magento-Cache-Debug', 'MISS', true], - ['X-Magento-Tags', 'tag,tag2,' . \Magento\PageCache\Model\Cache\Type::CACHE_TAG] + $this->assertSame( + $this->resultMock, + $this->plugin->afterRenderResult($this->resultMock, $this->resultMock, $this->responseMock) ); - - $this->response->expects($this->once())->method('clearHeader')->with('X-Magento-Tags'); - $this->registry->expects($this->once())->method('registry')->with('use_page_cache_plugin') - ->will($this->returnValue(true)); - $this->kernel->expects($this->once())->method('process')->with($this->response); - - $result = call_user_func($this->closure); - $this->assertSame($result, $this->plugin->aroundRenderResult($this->subject, $this->closure, $this->response)); } } -- GitLab From 8a7619bc19dbafebeb886dcdbcd424ec4944c491 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Wed, 17 Aug 2016 12:57:20 +0300 Subject: [PATCH 433/838] MAGETWO-54247: Typo on Create Product Configurations Slideout --- .../product/edit/attribute/steps/attributes_values.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml index ee53280e90b..05ea00cd9b5 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/attribute/steps/attributes_values.phtml @@ -14,7 +14,7 @@ ); ?></h2> <div class="steps-wizard-info"> <span><?php echo $block->escapeHtml( - __('Select values from each attribute to include in this product. Each unique combination of values creates a unigue product SKU.') + __('Select values from each attribute to include in this product. Each unique combination of values creates a unique product SKU.') );?></span> </div> <div data-bind="foreach: attributes, sortableList: attributes"> -- GitLab From 4276e5be35ac7758420c6fa14a0956de9098cf29 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 14:03:12 +0300 Subject: [PATCH 434/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/ShipmentFactory.php | 2 +- .../Model/Order/ShipmentQuantityValidator.php | 2 +- .../Adminhtml/Order/Shipment/Save.php | 8 ++++++- .../Adminhtml/Order/ShipmentLoader.php | 22 ------------------- 4 files changed, 9 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 9127bba57a1..3f9dc814399 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model\Order; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; @@ -89,7 +90,6 @@ class ShipmentFactory array $items = [] ) { $totalQty = 0; - foreach ($order->getAllItems() as $orderItem) { if (!$this->canShipItem($orderItem, $items)) { continue; diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index fb3fc9818c1..e5b7d5d52b6 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -107,6 +107,6 @@ class ShipmentQuantityValidator implements ValidatorInterface */ private function isQtyAvailable(Item $orderItem, $qty) { - return $qty <= $orderItem->getQtyToShip() || $orderItem->isDummy(true); + return $qty !== 0 && ($qty <= $orderItem->getQtyToShip() || $orderItem->isDummy(true)); } } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index 6898ade5a77..30a22f6157f 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -127,11 +127,17 @@ class Save extends \Magento\Backend\App\Action $shipment->setCustomerNote($data['comment_text']); $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify'])); } + $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label']; + $errorMessages = $this->getShipmentValidator()->validate($shipment, [ShipmentQuantityValidator::class]); + if (!empty($errorMessages)) { + throw new \Magento\Sales\Exception\DocumentValidationException( + __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + ); + } $shipment->register(); $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email'])); $responseAjax = new \Magento\Framework\DataObject(); - $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label']; if ($isNeedCreateLabel) { $this->labelGenerator->create($shipment, $this->_request); diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index 2c49937edf7..0b537d39005 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -143,31 +143,9 @@ class ShipmentLoader extends DataObject $this->getItemQtys(), $this->getTracking() ); - $errorMessages = $this->getShipmentValidator()->validate( - $shipment, - [ShipmentQuantityValidator::class] - ); - if (!empty($errorMessages)) { - throw new \Magento\Framework\Exception\LocalizedException( - __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) - ); - } } $this->registry->register('current_shipment', $shipment); return $shipment; } - - /** - * @return ShipmentValidatorInterface - * @deprecated - */ - private function getShipmentValidator() - { - if ($this->shipmentValidator === null) { - $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); - } - - return $this->shipmentValidator; - } } -- GitLab From ba54a989e562e9c99185468de07f62a4c37dd622 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Wed, 17 Aug 2016 14:23:06 +0300 Subject: [PATCH 435/838] MAGETWO-54677: Added Arguments interface --- .../Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 18ad880c76f..ae1140815ac 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -10,6 +10,7 @@ use Magento\Framework\EntityManager\HydratorPool; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; use Magento\Sales\Api\Data\ShipmentCommentInterface; +use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\Data\ShipmentItemCreationInterface; use Magento\Sales\Api\Data\ShipmentPackageInterface; @@ -62,6 +63,7 @@ class ShipmentDocumentFactory * @param ShipmentCommentCreationInterface|null $comment * @param bool $appendComment * @param array $packages + * @param ShipmentCreationArgumentsInterface $arguments * @return Shipment * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ @@ -71,7 +73,8 @@ class ShipmentDocumentFactory $tracks = [], ShipmentCommentCreationInterface $comment = null, $appendComment = false, - $packages = [] + $packages = [], + ShipmentCreationArgumentsInterface $arguments = [] ) { $shipmentItems = $this->itemsToArray($items); -- GitLab From 00509c10ea0a06067e4132f1d74884cd643bd3e0 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Aug 2016 14:41:03 +0300 Subject: [PATCH 436/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage - Fixed unit test; --- .../Model/Plugin/AroundProductRepositorySaveTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php index ff50f8174c9..bb1c8908673 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php @@ -113,7 +113,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->result, - $this->plugin->afterSave($this->productRepository, $this->product, $this->product) + $this->plugin->afterSave($this->productRepository, $this->result, $this->product) ); } @@ -139,7 +139,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->result, - $this->plugin->afterSave($this->productRepository, $this->product, $this->product) + $this->plugin->afterSave($this->productRepository, $this->result, $this->product) ); } @@ -182,7 +182,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $product->expects(static::never()) ->method('getData'); - $this->plugin->afterSave($this->productRepository, $this->product, $this->product); + $this->plugin->afterSave($this->productRepository, $this->result, $this->product); } /** @@ -239,7 +239,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->with($attributeCode) ->willReturn(false); - $this->plugin->afterSave($this->productRepository, $this->product, $this->product); + $this->plugin->afterSave($this->productRepository, $this->result, $this->product); } /** @@ -294,6 +294,6 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->with($attributeCode) ->willReturn($attributeId); - $this->plugin->afterSave($this->productRepository, $this->product, $this->product); + $this->plugin->afterSave($this->productRepository, $this->result, $this->product); } } -- GitLab From f89a52bb64bee6544a12cde487c3ae483469fd39 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 14:51:09 +0300 Subject: [PATCH 437/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php | 1 + app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index d2d7e366e9a..f36889353af 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -48,6 +48,7 @@ class TrackCreation implements ShipmentTrackCreationInterface $this->trackNumber = $trackNumber; return $this; } + /** * {@inheritdoc} */ diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 18ad880c76f..15486cfde2e 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -114,7 +114,6 @@ class ShipmentDocumentFactory return $shipment; } - /** * Convert Items To Array * -- GitLab From 9de64f2548bce6d60b9bd91e8896e53bf29f9eae Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 14:52:41 +0300 Subject: [PATCH 438/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 4ce3257bb46..adedf2fed3c 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -74,7 +74,7 @@ class ShipmentDocumentFactory ShipmentCommentCreationInterface $comment = null, $appendComment = false, $packages = [], - ShipmentCreationArgumentsInterface $arguments = [] + ShipmentCreationArgumentsInterface $arguments = null ) { $shipmentItems = $this->itemsToArray($items); -- GitLab From 64113951c2d4ce452a3710a847908c86b975e787 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 14:57:03 +0300 Subject: [PATCH 439/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/ShipmentFactory.php | 5 ----- .../Adminhtml/Order/Shipment/Save.php | 20 +++++++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index 3f9dc814399..db0d8a02419 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -35,11 +35,6 @@ class ShipmentFactory */ protected $instanceName; - /** - * @var ShipmentValidatorInterface - */ - private $shipmentValidator; - /** * Factory constructor. * diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index 30a22f6157f..b7e0834c11b 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -8,10 +8,12 @@ namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; use Magento\Framework\App\ObjectManager; -use Magento\Sales\Model\Order\Email\Sender\ShipmentSender; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; use Magento\Sales\Model\Order\ShipmentQuantityValidator; +/** + * Class Save + */ class Save extends \Magento\Backend\App\Action { /** @@ -32,7 +34,7 @@ class Save extends \Magento\Backend\App\Action protected $labelGenerator; /** - * @var ShipmentSender + * @var \Magento\Sales\Model\Order\Email\Sender\ShipmentSender */ protected $shipmentSender; @@ -42,16 +44,16 @@ class Save extends \Magento\Backend\App\Action private $shipmentValidator; /** - * @param Action\Context $context + * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader * @param \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator - * @param ShipmentSender $shipmentSender + * @param \Magento\Sales\Model\Order\Email\Sender\ShipmentSender $shipmentSender */ public function __construct( - Action\Context $context, + \Magento\Backend\App\Action\Context $context, \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader, \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator, - ShipmentSender $shipmentSender + \Magento\Sales\Model\Order\Email\Sender\ShipmentSender $shipmentSender ) { $this->shipmentLoader = $shipmentLoader; $this->labelGenerator = $labelGenerator; @@ -183,13 +185,15 @@ class Save extends \Magento\Backend\App\Action } /** - * @return ShipmentValidatorInterface + * @return \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface * @deprecated */ private function getShipmentValidator() { if ($this->shipmentValidator === null) { - $this->shipmentValidator = ObjectManager::getInstance()->get(ShipmentValidatorInterface::class); + $this->shipmentValidator = ObjectManager::getInstance()->get( + \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface::class + ); } return $this->shipmentValidator; -- GitLab From b1ee7023532d41ca0f13d7ebaac9e22226839b53 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 15:12:12 +0300 Subject: [PATCH 440/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Adminhtml/Order/Shipment/Save.php | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index b7e0834c11b..666ff569849 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -129,17 +129,19 @@ class Save extends \Magento\Backend\App\Action $shipment->setCustomerNote($data['comment_text']); $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify'])); } - $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label']; $errorMessages = $this->getShipmentValidator()->validate($shipment, [ShipmentQuantityValidator::class]); if (!empty($errorMessages)) { - throw new \Magento\Sales\Exception\DocumentValidationException( + $this->messageManager->addError( __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) ); + $this->_redirect('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]); + return; } $shipment->register(); $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email'])); $responseAjax = new \Magento\Framework\DataObject(); + $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label']; if ($isNeedCreateLabel) { $this->labelGenerator->create($shipment, $this->_request); @@ -198,4 +200,20 @@ class Save extends \Magento\Backend\App\Action return $this->shipmentValidator; } + + /** + * @param $isNeedCreateLabel + * @param $responseAjax + * @param $message + */ + private function handleError($isNeedCreateLabel, $responseAjax, $message) + { + if ($isNeedCreateLabel) { + $responseAjax->setError(true); + $responseAjax->setMessage($message); + } else { + $this->messageManager->addError($message); + $this->_redirect('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]); + } + } } -- GitLab From a8d463b6ff870053073703dbe07b8bc3023eec6d Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 15:16:51 +0300 Subject: [PATCH 441/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 5 +---- app/code/Magento/Sales/Model/ShipOrder.php | 1 + .../Shipping/Controller/Adminhtml/Order/ShipmentLoader.php | 5 ----- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index adedf2fed3c..d9b7b51a229 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -9,11 +9,8 @@ namespace Magento\Sales\Model\Order; use Magento\Framework\EntityManager\HydratorPool; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; -use Magento\Sales\Api\Data\ShipmentCommentInterface; use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; -use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\Data\ShipmentItemCreationInterface; -use Magento\Sales\Api\Data\ShipmentPackageInterface; use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; use Magento\Sales\Model\Order\Shipment\TrackFactory; @@ -120,7 +117,7 @@ class ShipmentDocumentFactory /** * Convert Items To Array * - * @param InvoiceItemCreationInterface[] $items + * @param ShipmentItemCreationInterface[] $items * @return array */ private function itemsToArray($items = []) diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php index 4221676d927..b5498b1085b 100644 --- a/app/code/Magento/Sales/Model/ShipOrder.php +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -91,6 +91,7 @@ class ShipOrder implements ShipOrderInterface * @param OrderConfig $config * @param ShipmentRepositoryInterface $shipmentRepository * @param NotifierInterface $notifierInterface + * @param OrderRegistrarInterface $orderRegistrar * @param LoggerInterface $logger * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index 0b537d39005..c1ad9653937 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -56,11 +56,6 @@ class ShipmentLoader extends DataObject */ protected $orderRepository; - /** - * @var ShipmentValidatorInterface - */ - private $shipmentValidator; - /** * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param \Magento\Framework\Registry $registry -- GitLab From 73fe2cfcc7b7ef0e847f9c6837956470e0e4fd9a Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Wed, 17 Aug 2016 15:26:30 +0300 Subject: [PATCH 442/838] MAGETWO-54677: Fixed Unit tests --- .../Unit/Model/Order/ShipmentFactoryTest.php | 14 ------------- .../Adminhtml/Order/Shipment/SaveTest.php | 20 ++++++++++++++++++- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php index cbf637f1248..46d6ac62fc2 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentFactoryTest.php @@ -32,11 +32,6 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase */ protected $trackFactory; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $shipmentValidatorMock; - /** * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -71,9 +66,6 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase '', false ); - $this->shipmentValidatorMock = $this->getMockBuilder( - \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface::class - )->getMockForAbstractClass(); $this->subject = $objectManager->getObject( \Magento\Sales\Model\Order\ShipmentFactory::class, @@ -82,12 +74,6 @@ class ShipmentFactoryTest extends \PHPUnit_Framework_TestCase 'trackFactory' => $this->trackFactory ] ); - - $objectManager->setBackwardCompatibleProperty( - $this->subject, - 'shipmentValidator', - $this->shipmentValidatorMock - ); } /** diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php index af89f1a9146..bdc4dd17d10 100644 --- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php @@ -11,6 +11,9 @@ namespace Magento\Shipping\Test\Unit\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; use Magento\Sales\Model\Order\Email\Sender\ShipmentSender; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; +use Magento\Sales\Model\Order\ShipmentQuantityValidator; + /** * Class SaveTest * @@ -88,6 +91,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase */ protected $saveAction; + /** + * @var ShipmentValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentValidatorMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -210,6 +218,10 @@ class SaveTest extends \PHPUnit_Framework_TestCase ->method('getFormKeyValidator') ->will($this->returnValue($this->formKeyValidator)); + $this->shipmentValidatorMock = $this->getMockBuilder(ShipmentValidatorInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->saveAction = $objectManagerHelper->getObject( \Magento\Shipping\Controller\Adminhtml\Order\Shipment\Save::class, [ @@ -218,7 +230,8 @@ class SaveTest extends \PHPUnit_Framework_TestCase 'context' => $this->context, 'shipmentLoader' => $this->shipmentLoader, 'request' => $this->request, - 'response' => $this->response + 'response' => $this->response, + 'shipmentValidator' => $this->shipmentValidatorMock ] ); } @@ -346,6 +359,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($orderId)); $this->prepareRedirect($path, $arguments); + $this->shipmentValidatorMock->expects($this->once()) + ->method('validate') + ->with($shipment, [ShipmentQuantityValidator::class]) + ->willReturn([]); + $this->saveAction->execute(); $this->assertEquals($this->response, $this->saveAction->getResponse()); } -- GitLab From bafc685f4cb536077a836a41d4db312705f0a7b6 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 15:58:53 +0300 Subject: [PATCH 443/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Controller/Adminhtml/Order/Shipment/Save.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index 666ff569849..f20b98bca54 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -200,20 +200,4 @@ class Save extends \Magento\Backend\App\Action return $this->shipmentValidator; } - - /** - * @param $isNeedCreateLabel - * @param $responseAjax - * @param $message - */ - private function handleError($isNeedCreateLabel, $responseAjax, $message) - { - if ($isNeedCreateLabel) { - $responseAjax->setError(true); - $responseAjax->setMessage($message); - } else { - $this->messageManager->addError($message); - $this->_redirect('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]); - } - } } -- GitLab From 737fc07740324d6f83cbce4186bad0c5a9da53e8 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Wed, 17 Aug 2016 16:07:31 +0300 Subject: [PATCH 444/838] MAGETWO-54677: Fixed Unit tests --- .../Test/Unit/CustomAttributesMapperTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php index a39ad4afaa6..a766c28ba11 100644 --- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php +++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php @@ -48,12 +48,15 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase $metadataPool = $this->getMockBuilder(\Magento\Framework\EntityManager\MetadataPool::class) ->disableOriginalConstructor() - ->setMethods(['getMetadata']) + ->setMethods(['getMetadata', 'hasConfiguration']) ->getMock(); $metadataPool->expects($this->any()) ->method('getMetadata') ->with($this->equalTo(\Magento\Customer\Api\Data\AddressInterface::class)) ->will($this->returnValue($metadata)); + $metadataPool->expects($this->once()) + ->method('hasConfiguration') + ->willReturn(true); $searchCriteriaBuilder = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaBuilder::class) ->disableOriginalConstructor() @@ -76,6 +79,9 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase 'metadataPool' => $metadataPool, 'searchCriteriaBuilder' => $searchCriteriaBuilder ]); + + + $actual = $customAttributesMapper->entityToDatabase( \Magento\Customer\Api\Data\AddressInterface::class, [ -- GitLab From ef6dcd571302fb6a6522e01bd36cb9a266d2503b Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 16:08:18 +0300 Subject: [PATCH 445/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Model/Order/ShipmentDocumentFactory.php | 44 ++++++++----------- .../Adminhtml/Order/Shipment/Save.php | 3 +- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index d9b7b51a229..89821696962 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -6,14 +6,6 @@ namespace Magento\Sales\Model\Order; -use Magento\Framework\EntityManager\HydratorPool; -use Magento\Sales\Api\Data\OrderInterface; -use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; -use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; -use Magento\Sales\Api\Data\ShipmentItemCreationInterface; -use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; -use Magento\Sales\Model\Order\Shipment\TrackFactory; - /** * Class InvoiceDocumentFactory * @@ -22,31 +14,31 @@ use Magento\Sales\Model\Order\Shipment\TrackFactory; class ShipmentDocumentFactory { /** - * @var ShipmentFactory + * @var \Magento\Framework\EntityManager\HydratorPool */ private $shipmentFactory; /** - * @var TrackFactory + * @var \Magento\Sales\Model\Order\Shipment\TrackFactory */ private $trackFactory; /** - * @var HydratorPool + * @var \Magento\Framework\EntityManager\HydratorPool */ private $hydratorPool; /** * ShipmentDocumentFactory constructor. * - * @param ShipmentFactory $shipmentFactory - * @param HydratorPool $hydratorPool - * @param TrackFactory $trackFactory + * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory + * @param \Magento\Framework\EntityManager\HydratorPool $hydratorPool + * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory */ public function __construct( - ShipmentFactory $shipmentFactory, - HydratorPool $hydratorPool, - TrackFactory $trackFactory + \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory, + \Magento\Framework\EntityManager\HydratorPool $hydratorPool, + \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory ) { $this->shipmentFactory = $shipmentFactory; $this->trackFactory = $trackFactory; @@ -54,24 +46,24 @@ class ShipmentDocumentFactory } /** - * @param OrderInterface $order + * @param \Magento\Sales\Api\Data\OrderInterface $order * @param array $items * @param array $tracks - * @param ShipmentCommentCreationInterface|null $comment + * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment * @param bool $appendComment * @param array $packages - * @param ShipmentCreationArgumentsInterface $arguments + * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments * @return Shipment * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function create( - OrderInterface $order, + \Magento\Sales\Api\Data\OrderInterface $order, $items = [], $tracks = [], - ShipmentCommentCreationInterface $comment = null, + \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, $appendComment = false, $packages = [], - ShipmentCreationArgumentsInterface $arguments = null + \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null ) { $shipmentItems = $this->itemsToArray($items); @@ -108,7 +100,9 @@ class ShipmentDocumentFactory __('Please enter a tracking number.') ); } - $hydrator = $this->hydratorPool->getHydrator(ShipmentTrackCreationInterface::class); + $hydrator = $this->hydratorPool->getHydrator( + \Magento\Sales\Api\Data\ShipmentTrackCreationInterface::class + ); $shipment->addTrack($this->trackFactory->create(['data' => $hydrator->extract($track)])); } return $shipment; @@ -117,7 +111,7 @@ class ShipmentDocumentFactory /** * Convert Items To Array * - * @param ShipmentItemCreationInterface[] $items + * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items * @return array */ private function itemsToArray($items = []) diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index f20b98bca54..7ca75777544 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -8,7 +8,6 @@ namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; use Magento\Framework\App\ObjectManager; -use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; use Magento\Sales\Model\Order\ShipmentQuantityValidator; /** @@ -39,7 +38,7 @@ class Save extends \Magento\Backend\App\Action protected $shipmentSender; /** - * @var ShipmentValidatorInterface + * @var \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface */ private $shipmentValidator; -- GitLab From 242c60dfa320b086c41308ada4375bb87f51f556 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Wed, 17 Aug 2016 16:14:22 +0300 Subject: [PATCH 446/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../App/FrontController/VarnishPlugin.php | 64 +++--- .../App/FrontController/VarnishPluginTest.php | 186 ++++++++++-------- 2 files changed, 137 insertions(+), 113 deletions(-) diff --git a/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php b/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php index 1d716991f9d..d2a5dbf4942 100644 --- a/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php +++ b/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php @@ -5,61 +5,67 @@ */ namespace Magento\PageCache\Model\App\FrontController; +use Magento\PageCache\Model\Config; +use Magento\Framework\App\PageCache\Version; +use Magento\Framework\App\State as AppState; +use Magento\Framework\App\FrontControllerInterface; +use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\Http as ResponseHttp; +use Magento\Framework\Controller\ResultInterface; + /** * Varnish for processing builtin cache */ class VarnishPlugin { /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var Config */ - protected $config; + private $config; /** - * @var \Magento\Framework\App\PageCache\Version + * @var Version */ - protected $version; + private $version; /** - * @var \Magento\Framework\App\State + * @var AppState */ - protected $state; + private $state; /** - * @param \Magento\PageCache\Model\Config $config - * @param \Magento\Framework\App\PageCache\Version $version - * @param \Magento\Framework\App\State $state + * @param Config $config + * @param Version $version + * @param AppState $state */ - public function __construct( - \Magento\PageCache\Model\Config $config, - \Magento\Framework\App\PageCache\Version $version, - \Magento\Framework\App\State $state - ) { + public function __construct(Config $config, Version $version, AppState $state) + { $this->config = $config; $this->version = $version; $this->state = $state; } /** - * @param \Magento\Framework\App\FrontControllerInterface $subject - * @param callable $proceed - * @param \Magento\Framework\App\RequestInterface $request - * @return false|\Magento\Framework\App\Response\Http|\Magento\Framework\Controller\ResultInterface + * Perform response postprocessing + * + * @param FrontControllerInterface $subject + * @param ResponseInterface|ResultInterface $result + * @return ResponseHttp|ResultInterface|false + * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDispatch( - \Magento\Framework\App\FrontControllerInterface $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request - ) { - $response = $proceed($request); - if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled() - && $response instanceof \Magento\Framework\App\Response\Http) { + public function afterDispatch(FrontControllerInterface $subject, $result) + { + if ($this->config->getType() == Config::VARNISH && $this->config->isEnabled() + && $result instanceof ResponseHttp + ) { $this->version->process(); - if ($this->state->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) { - $response->setHeader('X-Magento-Debug', 1); + + if ($this->state->getMode() == AppState::MODE_DEVELOPER) { + $result->setHeader('X-Magento-Debug', 1); } } - return $response; + + return $result; } } diff --git a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php index 32328d7d027..486e1f2e04a 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php @@ -3,148 +3,166 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\PageCache\Test\Unit\Model\App\FrontController; use Magento\PageCache\Model\App\FrontController\VarnishPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\PageCache\Model\Config; +use Magento\Framework\App\PageCache\Version; +use Magento\Framework\App\State as AppState; +use Magento\Framework\App\FrontControllerInterface; +use Magento\Framework\App\Response\Http as ResponseHttp; +use Magento\Framework\Controller\ResultInterface; class VarnishPluginTest extends \PHPUnit_Framework_TestCase { /** * @var VarnishPlugin */ - protected $plugin; + private $plugin; /** - * @var \Magento\PageCache\Model\Config|\PHPUnit_Framework_MockObject_MockObject + * @var ObjectManagerHelper */ - protected $configMock; + private $objectManagerHelper; /** - * @var \Magento\Framework\App\PageCache\Version|\PHPUnit_Framework_MockObject_MockObject + * @var Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $versionMock; + private $configMock; /** - * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject + * @var Version|\PHPUnit_Framework_MockObject_MockObject */ - protected $stateMock; + private $versionMock; /** - * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject + * @var AppState|\PHPUnit_Framework_MockObject_MockObject */ - protected $responseMock; + private $stateMock; /** - * @var \Magento\Framework\App\FrontControllerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var FrontControllerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $frontControllerMock; + private $frontControllerMock; /** - * @var \Closure + * @var ResponseHttp|\PHPUnit_Framework_MockObject_MockObject */ - protected $closure; + private $responseMock; /** - * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ResultInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $requestMock; + private $resultMock; - /** - * SetUp - */ protected function setUp() { - $this->configMock = $this->getMock(\Magento\PageCache\Model\Config::class, [], [], '', false); - $this->versionMock = $this->getMock(\Magento\Framework\App\PageCache\Version::class, [], [], '', false); - $this->stateMock = $this->getMock(\Magento\Framework\App\State::class, [], [], '', false); - $this->frontControllerMock = $this->getMock( - \Magento\Framework\App\FrontControllerInterface::class, - [], - [], - '', - false - ); - $this->requestMock = $this->getMock(\Magento\Framework\App\RequestInterface::class, [], [], '', false); - $this->responseMock = $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false); - $response = $this->responseMock; - $this->closure = function () use ($response) { - return $response; - }; - $this->plugin = new \Magento\PageCache\Model\App\FrontController\VarnishPlugin( - $this->configMock, - $this->versionMock, - $this->stateMock + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + $this->versionMock = $this->getMockBuilder(Version::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stateMock = $this->getMockBuilder(AppState::class) + ->disableOriginalConstructor() + ->getMock(); + $this->frontControllerMock = $this->getMockBuilder(FrontControllerInterface::class) + ->getMockForAbstractClass(); + $this->responseMock = $this->getMockBuilder(ResponseHttp::class) + ->disableOriginalConstructor() + ->getMock(); + $this->resultMock = $this->getMockBuilder(ResultInterface::class) + ->getMockForAbstractClass(); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + VarnishPlugin::class, + [ + 'config' => $this->configMock, + 'version' => $this->versionMock, + 'state' => $this->stateMock + ] ); } /** - * @dataProvider dataProvider + * @param string $state + * @param int $countHeader + * + * @dataProvider afterDispatchDataProvider */ - public function testAroundDispatchReturnsCache($state, $countHeader, $countProcess, $countGetMode, $response) + public function testAfterDispatchReturnsCache($state, $countHeader) { - $this->configMock - ->expects($this->once()) + $this->configMock->expects(static::once()) ->method('isEnabled') - ->will($this->returnValue(true)); - $this->configMock - ->expects($this->once()) + ->willReturn(true); + $this->configMock->expects(static::once()) ->method('getType') - ->will($this->returnValue(\Magento\PageCache\Model\Config::VARNISH)); - $this->versionMock - ->expects($countProcess) + ->willReturn(Config::VARNISH); + $this->versionMock->expects(static::once()) ->method('process'); - $this->stateMock->expects($countGetMode) + $this->stateMock->expects(static::once()) ->method('getMode') - ->will($this->returnValue($state)); - $response->expects($countHeader) + ->willReturn($state); + $this->responseMock->expects(static::exactly($countHeader)) ->method('setHeader') ->with('X-Magento-Debug'); - $this->closure = function () use ($response) { - return $response; - }; + $this->assertSame( + $this->responseMock, + $this->plugin->afterDispatch($this->frontControllerMock, $this->responseMock) + ); + } - $this->plugin->aroundDispatch($this->frontControllerMock, $this->closure, $this->requestMock); + public function testAfterDispatchNotResponse() + { + $this->configMock->expects(static::once()) + ->method('isEnabled') + ->willReturn(true); + $this->configMock->expects(static::once()) + ->method('getType') + ->willReturn(Config::VARNISH); + $this->versionMock->expects(static::never()) + ->method('process'); + $this->stateMock->expects(static::never()) + ->method('getMode'); + $this->resultMock->expects(static::never()) + ->method('setHeader'); + + $this->assertSame( + $this->resultMock, + $this->plugin->afterDispatch($this->frontControllerMock, $this->resultMock) + ); } - /** - * @dataProvider dataProvider - */ - public function testAroundDispatchDisabled($state) + public function testAfterDispatchDisabled() { - $this->configMock - ->expects($this->any()) + $this->configMock->expects(static::any()) ->method('getType') - ->will($this->returnValue(null)); - $this->versionMock - ->expects($this->never()) + ->willReturn(null); + $this->versionMock->expects(static::never()) ->method('process'); - $this->stateMock->expects($this->any()) + $this->stateMock->expects(static::any()) ->method('getMode') - ->will($this->returnValue($state)); - $this->responseMock->expects($this->never()) + ->willReturn(AppState::MODE_DEVELOPER); + $this->responseMock->expects(static::never()) ->method('setHeader'); - $this->plugin->aroundDispatch($this->frontControllerMock, $this->closure, $this->requestMock); + + $this->assertSame( + $this->responseMock, + $this->plugin->afterDispatch($this->frontControllerMock, $this->responseMock) + ); } - public function dataProvider() + /** + * @return array + */ + public function afterDispatchDataProvider() { return [ - 'developer_mode' => [ - \Magento\Framework\App\State::MODE_DEVELOPER, - $this->once(), - $this->once(), - $this->once(), - $this->getMock(\Magento\Framework\App\Response\Http::class, [], [], '', false), - ], - 'production' => [ - \Magento\Framework\App\State::MODE_PRODUCTION, - $this->never(), - $this->never(), - $this->never(), - $this->getMock(\Magento\Framework\Controller\ResultInterface::class, [], [], '', false), - ], + 'developer_mode' => [AppState::MODE_DEVELOPER, 1], + 'production' => [AppState::MODE_PRODUCTION, 0] ]; } } -- GitLab From b8544a43bc20e120ba5d48f5663483b211388984 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 16:21:20 +0300 Subject: [PATCH 447/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Shipping/Controller/Adminhtml/Order/Shipment/Save.php | 1 + .../EntityManager/Test/Unit/CustomAttributesMapperTest.php | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index 7ca75777544..9be027576c2 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -12,6 +12,7 @@ use Magento\Sales\Model\Order\ShipmentQuantityValidator; /** * Class Save + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Save extends \Magento\Backend\App\Action { diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php index a766c28ba11..4c351efd936 100644 --- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php +++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php @@ -80,8 +80,6 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase 'searchCriteriaBuilder' => $searchCriteriaBuilder ]); - - $actual = $customAttributesMapper->entityToDatabase( \Magento\Customer\Api\Data\AddressInterface::class, [ -- GitLab From cdaf9b2ce3c68fe3f6aaec40816b8f77b6a8c984 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 16:41:09 +0300 Subject: [PATCH 448/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Category/Plugin/Category/Remove.php | 42 ++++++------------- .../Category/Plugin/Category/RemoveTest.php | 27 ++++-------- .../Product/Link/RelationPersister.php | 36 ++++++---------- .../Product/Link/RelationPersisterTest.php | 34 +++++---------- .../Model/Plugin/CustomerPlugin.php | 24 ++++++----- .../Unit/Model/Plugin/CustomerPluginTest.php | 11 +++-- .../Order/Plugin/Authorization.php | 16 +++---- 7 files changed, 71 insertions(+), 119 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php index 1a81c73c157..1259fdf2e76 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php @@ -23,9 +23,6 @@ class Remove /** @var ChildrenCategoriesProvider */ protected $childrenCategoriesProvider; - /** @var array */ - private $categoryIds; - /** * @param UrlPersistInterface $urlPersist * @param ProductUrlRewriteGenerator $productUrlRewriteGenerator @@ -41,45 +38,30 @@ class Remove $this->childrenCategoriesProvider = $childrenCategoriesProvider; } - /** - * Save category ids before delete - * - * @param \Magento\Catalog\Model\ResourceModel\Category $subject - * @param \Magento\Framework\DataObject|int|string $object - * @return array - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function beforeDelete(\Magento\Catalog\Model\ResourceModel\Category $subject, $object) - { - if ($object instanceof CategoryInterface) { - $this->categoryIds = $this->childrenCategoriesProvider->getChildrenIds($object, true); - $this->categoryIds[] = $object->getId(); - } - return [$object]; - } - /** * Remove product urls from storage * * @param \Magento\Catalog\Model\ResourceModel\Category $subject - * @param \Magento\Catalog\Model\ResourceModel\Category $result - * @param \Magento\Framework\DataObject|int|string $object - * @return \Magento\Catalog\Model\ResourceModel\Category + * @param callable $proceed + * @param CategoryInterface $category + * @return mixed * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterDelete( + public function aroundDelete( \Magento\Catalog\Model\ResourceModel\Category $subject, - \Magento\Catalog\Model\ResourceModel\Category $result, - $object + \Closure $proceed, + CategoryInterface $category ) { - if ($object instanceof CategoryInterface) { - foreach ($this->categoryIds as $categoryId) { - $this->deleteRewritesForCategory($categoryId); - } + $categoryIds = $this->childrenCategoriesProvider->getChildrenIds($category, true); + $categoryIds[] = $category->getId(); + $result = $proceed($category); + foreach ($categoryIds as $categoryId) { + $this->deleteRewritesForCategory($categoryId); } return $result; } + /** * Remove url rewrites by categoryId * diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php index 8ea717a05b8..73f03ed3f9a 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php @@ -11,6 +11,7 @@ use Magento\UrlRewrite\Model\UrlPersistInterface; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; use Magento\Catalog\Model\Category; +use Magento\Catalog\Api\Data\CategoryInterface; class RemoveTest extends \PHPUnit_Framework_TestCase { @@ -54,9 +55,12 @@ class RemoveTest extends \PHPUnit_Framework_TestCase ->getMock(); } - public function testBeforeDelete() + public function testAroundDelete() { - $expectedResult = [$this->objectMock]; + $closureSubject = $this->subjectMock; + $proceed = function (CategoryInterface $category) use ($closureSubject) { + return $closureSubject; + }; $plugin = $this->objectManager->getObject( Remove::class, [ @@ -71,28 +75,11 @@ class RemoveTest extends \PHPUnit_Framework_TestCase $this->objectMock->expects($this->once()) ->method('getId') ->willReturn(1); - $this->assertEquals( - $expectedResult, - $plugin->beforeDelete($this->subjectMock, $this->objectMock) - ); - } - - public function testAfterDelete() - { - $categoryIds = [1]; $this->urlPersistMock->expects($this->exactly(2)) ->method('deleteByData'); - $plugin = $this->objectManager->getObject( - Remove::class, - [ - 'urlPersist' => $this->urlPersistMock, - 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock, - 'categoryIds' => $categoryIds - ] - ); $this->assertEquals( $this->subjectMock, - $plugin->afterDelete($this->subjectMock, $this->subjectMock, $this->objectMock) + $plugin->aroundDelete($this->subjectMock, $proceed, $this->objectMock) ); } } diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php index 4fb61cf7b16..fe937abfe59 100644 --- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php +++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php @@ -9,7 +9,6 @@ namespace Magento\GroupedProduct\Model\ResourceModel\Product\Link; use Magento\Catalog\Model\ProductLink\LinkFactory; use Magento\Catalog\Model\ResourceModel\Product\Link; use Magento\Catalog\Model\ResourceModel\Product\Relation; -use Magento\Catalog\Model\ProductLink\Link as ProductLink; use Magento\GroupedProduct\Model\ResourceModel\Product\Link as GroupedLink; class RelationPersister @@ -24,11 +23,6 @@ class RelationPersister */ private $linkFactory; - /** - * @var ProductLink - */ - private $link; - /** * RelationPersister constructor. * @@ -64,29 +58,23 @@ class RelationPersister } /** + * Remove grouped products from product relation table + * * @param Link $subject + * @param \Closure $proceed * @param int $linkId - * @return array - */ - public function beforeDeleteProductLink(Link $subject, $linkId) - { - $this->link = $this->linkFactory->create(); - $subject->load($this->link, $linkId, $subject->getIdFieldName()); - return [$linkId]; - } - - /** - * @param Link $subject - * @param int $result - * @return int - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @return Link */ - public function afterDeleteProductLink(Link $subject, $result) + public function aroundDeleteProductLink(Link $subject, \Closure $proceed, $linkId) { - if ($this->link->getLinkTypeId() == GroupedLink::LINK_TYPE_GROUPED) { + /** @var \Magento\Catalog\Model\ProductLink\Link $link */ + $link = $this->linkFactory->create(); + $subject->load($link, $linkId, $subject->getIdFieldName()); + $result = $proceed($linkId); + if ($link->getLinkTypeId() == GroupedLink::LINK_TYPE_GROUPED) { $this->relationProcessor->removeRelations( - $this->link->getProductId(), - $this->link->getLinkedProductId() + $link->getProductId(), + $link->getLinkedProductId() ); } return $result; diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php index 0cf327fd459..eb78d1d7219 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php @@ -84,29 +84,14 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase )); } - public function testBeforeDeleteProductLink() + public function testAroundDeleteProductLink() { - $this->subject->expects($this->any())->method('getIdFieldName')->willReturn('id'); - $this->subject->expects($this->once())->method('load')->with($this->link, 155, 'id'); - $this->assertEquals( - [155], - $this->object->beforeDeleteProductLink( - $this->subject, - 155 - ) - ); - } + $subject = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Link::class) + ->disableOriginalConstructor() + ->getMock(); + $subject->expects($this->any())->method('getIdFieldName')->willReturn('id'); + $subject->expects($this->once())->method('load')->with($this->link, 155, 'id'); - public function testAfterDeleteProductLink() - { - $object = $this->objectManager->getObject( - RelationPersister::class, - [ - 'relationProcessor' => $this->relationProcessor, - 'linkFactory' => $this->linkFactory, - 'link' => $this->link - ] - ); $this->link->expects($this->any()) ->method('getLinkTypeId') ->willReturn(\Magento\GroupedProduct\Model\ResourceModel\Product\Link::LINK_TYPE_GROUPED); @@ -119,9 +104,10 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase $this->relationProcessor->expects($this->once())->method('removeRelations')->with(12, 13); $this->assertEquals( - 155, - $object->afterDeleteProductLink( - $this->subject, + $subject, + $this->object->aroundDeleteProductLink( + $subject, + function() use ($subject) { return $subject; }, 155 ) ); diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index 5fa6882ba71..a9e9a6abb97 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -34,17 +34,16 @@ class CustomerPlugin * * @param CustomerRepository $subject * @param CustomerInterface $result - * @param CustomerInterface $customer * @return CustomerInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterSave(CustomerRepository $subject, CustomerInterface $result, CustomerInterface $customer) + public function afterSave(CustomerRepository $subject, CustomerInterface $result) { $this->subscriberFactory->create()->updateSubscription($result->getId()); - if ($result->getId() && $customer->getExtensionAttributes()) { - if ($customer->getExtensionAttributes()->getIsSubscribed() === true) { + if ($result->getId() && $result->getExtensionAttributes()) { + if ($result->getExtensionAttributes()->getIsSubscribed() === true) { $this->subscriberFactory->create()->subscribeCustomerById($result->getId()); - } elseif ($customer->getExtensionAttributes()->getIsSubscribed() === false) { + } elseif ($result->getExtensionAttributes()->getIsSubscribed() === false) { $this->subscriberFactory->create()->unsubscribeCustomerById($result->getId()); } } @@ -52,16 +51,21 @@ class CustomerPlugin } /** - * Plugin after delete customer that updates any newsletter subscription that may have existed. + * Plugin around delete customer that updates any newsletter subscription that may have existed. * * @param CustomerRepository $subject - * @param bool $result - * @param int $customerId + * @param callable $deleteCustomerById Function we are wrapping around + * @param int $customerId Input to the function * @return bool */ - public function afterDeleteById(CustomerRepository $subject, $result, $customerId) - { + public function aroundDeleteById( + CustomerRepository $subject, + callable $deleteCustomerById, + $customerId + ) { $customer = $subject->getById($customerId); + $result = $deleteCustomerById($customerId); + /** @var \Magento\Newsletter\Model\Subscriber $subscriber */ $subscriber = $this->subscriberFactory->create(); $subscriber->loadByEmail($customer->getEmail()); if ($subscriber->getId()) { diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php index bad949adec6..2975d8aaeb4 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php @@ -72,7 +72,7 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->method("getId") ->willReturn($customerId); - $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer, $customer)); + $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer)); } /** @@ -125,7 +125,7 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->method("getId") ->willReturn($customerId); - $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer, $customer)); + $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer)); } public function testAfterDelete() @@ -140,9 +140,12 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase $this->assertEquals(true, $this->plugin->afterDelete($subject, true, $customer)); } - public function testAfterDeleteById() + public function testAroundDeleteById() { $customerId = 1; + $deleteCustomerById = function () { + return true; + }; $subject = $this->getMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $customer = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class); $subject->expects($this->once())->method('getById')->willReturn($customer); @@ -151,6 +154,6 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase $this->subscriber->expects($this->once())->method('getId')->willReturn(1); $this->subscriber->expects($this->once())->method('delete')->willReturnSelf(); - $this->assertEquals(true, $this->plugin->afterDeleteById($subject, true, $customerId)); + $this->assertEquals(true, $this->plugin->aroundDeleteById($subject, $deleteCustomerById, $customerId)); } } diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php index 401c644b319..f6b459ba463 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Plugin/Authorization.php @@ -8,6 +8,8 @@ namespace Magento\Sales\Model\ResourceModel\Order\Plugin; use Magento\Authorization\Model\UserContextInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\ResourceModel\Order as ResourceOrder; class Authorization { @@ -26,19 +28,19 @@ class Authorization } /** - * @param \Magento\Sales\Model\ResourceModel\Order $subject - * @param \Magento\Sales\Model\ResourceModel\Order $result + * @param ResourceOrder $subject + * @param ResourceOrder $result * @param \Magento\Framework\Model\AbstractModel $order - * @return \Magento\Sales\Model\ResourceModel\Order + * @return ResourceOrder * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterLoad( - \Magento\Sales\Model\ResourceModel\Order $subject, - \Magento\Sales\Model\ResourceModel\Order $result, + ResourceOrder $subject, + ResourceOrder $result, \Magento\Framework\Model\AbstractModel $order ) { - if ($order instanceof \Magento\Sales\Model\Order) { + if ($order instanceof Order) { if (!$this->isAllowed($order)) { throw NoSuchEntityException::singleField('orderId', $order->getId()); } @@ -52,7 +54,7 @@ class Authorization * @param \Magento\Sales\Model\Order $order * @return bool */ - protected function isAllowed(\Magento\Sales\Model\Order $order) + protected function isAllowed(Order $order) { return $this->userContext->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER ? $order->getCustomerId() == $this->userContext->getUserId() -- GitLab From f32cec2cc3e95254e8b4f12ebed342ee60098de9 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 16:43:46 +0300 Subject: [PATCH 449/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php index 1259fdf2e76..91bf053304c 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Remove.php @@ -61,7 +61,6 @@ class Remove return $result; } - /** * Remove url rewrites by categoryId * -- GitLab From f3188efe084e3badf225f453a692f0aae9a640d9 Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Wed, 17 Aug 2016 17:02:25 +0300 Subject: [PATCH 450/838] MAGETWO-56497: Create API test --- .../Sales/Service/V1/ShipOrderTest.php | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php new file mode 100644 index 00000000000..8de7c4dc7f6 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipOrderTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Service\V1; + +/** + * API test for creation of Shipment for certain Order. + */ +class ShipOrderTest extends \Magento\TestFramework\TestCase\WebapiAbstract +{ + const SERVICE_READ_NAME = 'salesShipOrderV1'; + const SERVICE_VERSION = 'V1'; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var \Magento\Sales\Api\ShipmentRepositoryInterface + */ + private $shipmentRepository; + + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + $this->shipmentRepository = $this->objectManager->get( + \Magento\Sales\Api\ShipmentRepositoryInterface::class + ); + } + + /** + * @magentoApiDataFixture Magento/Sales/_files/order_new.php + */ + public function testShipOrder() + { + /** @var \Magento\Sales\Model\Order $existingOrder */ + $existingOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class) + ->loadByIncrementId('100000001'); + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/order/' . $existingOrder->getId() . '/ship', + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_READ_NAME, + 'serviceVersion' => self::SERVICE_VERSION, + 'operation' => self::SERVICE_READ_NAME . 'execute', + ], + ]; + + $requestData = [ + 'orderId' => $existingOrder->getId(), + 'items' => [], + 'comment' => [ + 'comment' => 'Test Comment', + 'is_visible_on_front' => 1, + ], + 'tracks' => [ + [ + 'track_number' => 'TEST_TRACK_0001', + 'title' => 'Simple shipment track', + 'carrier_code' => 'UPS' + ] + ] + ]; + + /** @var \Magento\Sales\Api\Data\OrderItemInterface $item */ + foreach ($existingOrder->getAllItems() as $item) { + $requestData['items'][] = [ + 'order_item_id' => $item->getItemId(), + 'qty' => $item->getQtyOrdered(), + ]; + } + + $result = $this->_webApiCall($serviceInfo, $requestData); + + $this->assertNotEmpty($result); + + try { + $this->shipmentRepository->get($result); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + $this->fail('Failed asserting that Shipment was created'); + } + + /** @var \Magento\Sales\Model\Order $updatedOrder */ + $updatedOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class) + ->loadByIncrementId('100000001'); + + $this->assertNotEquals( + $existingOrder->getStatus(), + $updatedOrder->getStatus(), + 'Failed asserting that Order status was changed' + ); + } +} -- GitLab From 8e062f344c0d75a9a43d9a6bf6b1c54be213e7cd Mon Sep 17 00:00:00 2001 From: Nadiya Syvokonenko <nsyvokonenko@magento.com> Date: Wed, 17 Aug 2016 17:05:13 +0300 Subject: [PATCH 451/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface - add unit test --- .../Model/Order/ShipmentDocumentFactory.php | 14 +- .../Sales/Test/Unit/Model/ShipOrderTest.php | 429 ++++++++++++++++++ 2 files changed, 436 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 89821696962..baf6acbd279 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -47,22 +47,22 @@ class ShipmentDocumentFactory /** * @param \Magento\Sales\Api\Data\OrderInterface $order - * @param array $items - * @param array $tracks + * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items + * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment * @param bool $appendComment - * @param array $packages - * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments + * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments * @return Shipment * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function create( \Magento\Sales\Api\Data\OrderInterface $order, - $items = [], - $tracks = [], + array $items = [], + array $tracks = [], \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, $appendComment = false, - $packages = [], + array $packages = [], \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null ) { diff --git a/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php new file mode 100644 index 00000000000..43f8e16a66c --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php @@ -0,0 +1,429 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; +use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentPackageInterface; +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Api\ShipmentRepositoryInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Config as OrderConfig; +use Magento\Sales\Model\Order\OrderStateResolverInterface; +use Magento\Sales\Model\Order\OrderValidatorInterface; +use Magento\Sales\Model\Order\ShipmentDocumentFactory; +use Magento\Sales\Model\Order\Shipment\NotifierInterface; +use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface; +use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; +use Magento\Sales\Model\ShipOrder; +use Psr\Log\LoggerInterface; + +/** + * Class ShipOrderTest + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ShipOrderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + */ + private $resourceConnectionMock; + + /** + * @var OrderRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderRepositoryMock; + + /** + * @var ShipmentDocumentFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentDocumentFactoryMock; + + /** + * @var ShipmentValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentValidatorMock; + + /** + * @var OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderValidatorMock; + + /** + * @var OrderRegistrarInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderRegistrarMock; + + /** + * @var OrderStateResolverInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderStateResolverMock; + + /** + * @var OrderConfig|\PHPUnit_Framework_MockObject_MockObject + */ + private $configMock; + + /** + * @var ShipmentRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentRepositoryMock; + + /** + * @var NotifierInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $notifierInterfaceMock; + + /** + * @var ShipOrder|\PHPUnit_Framework_MockObject_MockObject + */ + private $model; + + /** + * @var ShipmentCreationArgumentsInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentCommentCreationMock; + + /** + * @var ShipmentCommentCreationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentCreationArgumentsMock; + + /** + * @var OrderInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var ShipmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentMock; + + /** + * @var AdapterInterface + */ + private $adapterMock; + + /** + * @var ShipmentTrackCreationInterface + */ + private $trackMock; + + /** + * @var ShipmentPackageInterface + */ + private $packageMock; + + /** + * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + + protected function setUp() + { + $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->shipmentDocumentFactoryMock = $this->getMockBuilder(ShipmentDocumentFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->shipmentValidatorMock = $this->getMockBuilder(ShipmentValidatorInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->orderValidatorMock = $this->getMockBuilder(OrderValidatorInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->orderRegistrarMock = $this->getMockBuilder(OrderRegistrarInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->orderStateResolverMock = $this->getMockBuilder(OrderStateResolverInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->configMock = $this->getMockBuilder(OrderConfig::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->shipmentRepositoryMock = $this->getMockBuilder(ShipmentRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->notifierInterfaceMock = $this->getMockBuilder(NotifierInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->loggerMock = $this->getMockBuilder(LoggerInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->shipmentCommentCreationMock = $this->getMockBuilder(ShipmentCommentCreationInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->shipmentCreationArgumentsMock = $this->getMockBuilder(ShipmentCreationArgumentsInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->orderMock = $this->getMockBuilder(OrderInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->packageMock = $this->getMockBuilder(ShipmentPackageInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->trackMock = $this->getMockBuilder(ShipmentTrackCreationInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->adapterMock = $this->getMockBuilder(AdapterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->model = $helper->getObject( + ShipOrder::class, + [ + 'resourceConnection' => $this->resourceConnectionMock, + 'orderRepository' => $this->orderRepositoryMock, + 'shipmentRepository' => $this->shipmentRepositoryMock, + 'shipmentDocumentFactory' => $this->shipmentDocumentFactoryMock, + 'shipmentValidator' => $this->shipmentValidatorMock, + 'orderValidator' => $this->orderValidatorMock, + 'orderStateResolver' => $this->orderStateResolverMock, + 'orderRegistrar' => $this->orderRegistrarMock, + 'notifierInterface' => $this->notifierInterfaceMock, + 'config' => $this->configMock, + 'logger' => $this->loggerMock + ] + ); + } + + /** + * @dataProvider dataProvider + */ + public function testExecute($orderId, $items, $notify, $appendComment) + { + $this->resourceConnectionMock->expects($this->once()) + ->method('getConnection') + ->with('sales') + ->willReturn($this->adapterMock); + + $this->orderRepositoryMock->expects($this->once()) + ->method('get') + ->willReturn($this->orderMock); + + $this->shipmentDocumentFactoryMock->expects($this->once()) + ->method('create') + ->with( + $this->orderMock, + $items, + [$this->trackMock], + $this->shipmentCommentCreationMock, + ($appendComment && $notify), + [$this->packageMock], + $this->shipmentCreationArgumentsMock + )->willReturn($this->shipmentMock); + + $this->shipmentValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->shipmentMock) + ->willReturn([]); + $this->orderValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->orderMock) + ->willReturn([]); + + $this->orderRegistrarMock->expects($this->once()) + ->method('register') + ->with($this->orderMock, $this->shipmentMock) + ->willReturn($this->orderMock); + + $this->orderStateResolverMock->expects($this->once()) + ->method('getStateForOrder') + ->with($this->orderMock, [OrderStateResolverInterface::IN_PROGRESS]) + ->willReturn(Order::STATE_PROCESSING); + + $this->orderMock->expects($this->once()) + ->method('setState') + ->with(Order::STATE_PROCESSING) + ->willReturnSelf(); + + $this->orderMock->expects($this->once()) + ->method('getState') + ->willReturn(Order::STATE_PROCESSING); + + $this->configMock->expects($this->once()) + ->method('getStateDefaultStatus') + ->with(Order::STATE_PROCESSING) + ->willReturn('Processing'); + + $this->orderMock->expects($this->once()) + ->method('setStatus') + ->with('Processing') + ->willReturnSelf(); + + $this->shipmentRepositoryMock->expects($this->once()) + ->method('save') + ->with($this->shipmentMock) + ->willReturn($this->shipmentMock); + + $this->orderRepositoryMock->expects($this->once()) + ->method('save') + ->with($this->orderMock) + ->willReturn($this->orderMock); + + if ($notify) { + $this->notifierInterfaceMock->expects($this->once()) + ->method('notify') + ->with($this->orderMock, $this->shipmentMock, $this->shipmentCommentCreationMock); + } + + $this->shipmentMock->expects($this->once()) + ->method('getEntityId') + ->willReturn(2); + + $this->assertEquals( + 2, + $this->model->execute( + $orderId, + $items, + $notify, + $appendComment, + $this->shipmentCommentCreationMock, + [$this->trackMock], + [$this->packageMock], + $this->shipmentCreationArgumentsMock + ) + ); + } + + /** + * @expectedException \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface + */ + public function testDocumentValidationException() + { + $orderId = 1; + $items = [1 => 2]; + $notify = true; + $appendComment = true; + $errorMessages = ['error1', 'error2']; + + $this->orderRepositoryMock->expects($this->once()) + ->method('get') + ->willReturn($this->orderMock); + + $this->shipmentDocumentFactoryMock->expects($this->once()) + ->method('create') + ->with( + $this->orderMock, + $items, + [$this->trackMock], + $this->shipmentCommentCreationMock, + ($appendComment && $notify), + [$this->packageMock], + $this->shipmentCreationArgumentsMock + )->willReturn($this->shipmentMock); + + $this->shipmentValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->shipmentMock) + ->willReturn($errorMessages); + $this->orderValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->orderMock) + ->willReturn([]); + + $this->model->execute( + $orderId, + $items, + $notify, + $appendComment, + $this->shipmentCommentCreationMock, + [$this->trackMock], + [$this->packageMock], + $this->shipmentCreationArgumentsMock + ); + } + + /** + * @expectedException \Magento\Sales\Api\Exception\CouldNotShipExceptionInterface + */ + public function testCouldNotInvoiceException() + { + $orderId = 1; + $this->resourceConnectionMock->expects($this->once()) + ->method('getConnection') + ->with('sales') + ->willReturn($this->adapterMock); + + $this->orderRepositoryMock->expects($this->once()) + ->method('get') + ->willReturn($this->orderMock); + + $this->shipmentDocumentFactoryMock->expects($this->once()) + ->method('create') + ->with( + $this->orderMock + )->willReturn($this->shipmentMock); + + $this->shipmentValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->shipmentMock) + ->willReturn([]); + $this->orderValidatorMock->expects($this->once()) + ->method('validate') + ->with($this->orderMock) + ->willReturn([]); + $e = new \Exception(); + + $this->orderRegistrarMock->expects($this->once()) + ->method('register') + ->with($this->orderMock, $this->shipmentMock) + ->willThrowException($e); + + $this->loggerMock->expects($this->once()) + ->method('critical') + ->with($e); + + $this->adapterMock->expects($this->once()) + ->method('rollBack'); + + $this->model->execute( + $orderId + ); + } + + /** + * @return array + */ + public function dataProvider() + { + return [ + 'TestWithNotifyTrue' => [1, [1 => 2], true, true], + 'TestWithNotifyFalse' => [1, [1 => 2], false, true], + ]; + } +} -- GitLab From d834a1f00963ccd8c0e02887c53efa49af75b964 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Aug 2016 17:05:25 +0300 Subject: [PATCH 452/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage - Refactored before and after plugin back to around; --- .../Group/AttributeMapper/Plugin.php | 36 +++------ .../Group/AttributeMapper/PluginTest.php | 78 +++++++++---------- .../Store/App/Action/Plugin/Context.php | 15 ++-- .../Store/App/Action/Plugin/StoreCheck.php | 15 +--- .../Unit/App/Action/Plugin/ContextTest.php | 60 ++++---------- .../Unit/App/Action/Plugin/StoreCheckTest.php | 33 ++------ 6 files changed, 79 insertions(+), 158 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php index 77873eaba35..6f14a13e8e6 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Entity/Product/Attribute/Group/AttributeMapper/Plugin.php @@ -9,7 +9,6 @@ namespace Magento\ConfigurableProduct\Model\Entity\Product\Attribute\Group\Attri use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\AttributeFactory; use Magento\Framework\Registry; -use Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface; class Plugin { @@ -28,11 +27,6 @@ class Plugin */ protected $configurableAttributes; - /** - * @var int|string - */ - private $setId; - /** * @param AttributeFactory $attributeFactory * @param Registry $registry @@ -43,39 +37,29 @@ class Plugin $this->attributeFactory = $attributeFactory; } - /** - * @param AttributeMapperInterface $subject - * @return void - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function beforeMap(AttributeMapperInterface $subject) - { - $this->setId = $this->registry->registry('current_attribute_set')->getId(); - } - /** * Add is_configurable field to attribute presentation * - * @param AttributeMapperInterface $subject - * @param array $result + * @param \Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface $subject + * @param callable $proceed * @param \Magento\Eav\Model\Entity\Attribute $attribute * * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterMap( - AttributeMapperInterface $subject, - array $result, + public function aroundMap( + \Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface $subject, + \Closure $proceed, \Magento\Eav\Model\Entity\Attribute $attribute ) { - if (!isset($this->configurableAttributes[$this->setId])) { - $this->configurableAttributes[$this->setId] = $this->attributeFactory->create()->getUsedAttributes( - $this->setId - ); + $setId = $this->registry->registry('current_attribute_set')->getId(); + $result = $proceed($attribute); + if (!isset($this->configurableAttributes[$setId])) { + $this->configurableAttributes[$setId] = $this->attributeFactory->create()->getUsedAttributes($setId); } $result['is_configurable'] = (int)in_array( $attribute->getAttributeId(), - $this->configurableAttributes[$this->setId] + $this->configurableAttributes[$setId] ); return $result; } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php index 70663f943be..ea49bf0da16 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Entity/Product/Attribute/Group/AttributeMapper/PluginTest.php @@ -6,7 +6,6 @@ namespace Magento\ConfigurableProduct\Test\Unit\Model\Entity\Product\Attribute\Group\AttributeMapper; use Magento\Eav\Model\Entity\Attribute; -use Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class PluginTest extends \PHPUnit_Framework_TestCase @@ -27,7 +26,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase private $attributeFactory; /** - * @var Attribute|\PHPUnit_Framework_MockObject_MockObject + * @var \PHPUnit_Framework_MockObject_MockObject */ private $attribute; @@ -36,11 +35,6 @@ class PluginTest extends \PHPUnit_Framework_TestCase */ private $magentoObject; - /** - * @var AttributeMapperInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $attributeMapper; - protected function setUp() { $helper = new ObjectManager($this); @@ -57,56 +51,62 @@ class PluginTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $this->magentoObject = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->setMethods(['getId']) - ->disableOriginalConstructor() - ->getMock(); - - $this->attributeMapper = $this->getMockBuilder(AttributeMapperInterface::class) + $this->attribute = $this->getMockBuilder( + \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute::class + ) + ->setMethods(['getUsedAttributes', 'getAttributeId', '__wakeup']) ->disableOriginalConstructor() ->getMock(); - $this->attribute = $this->getMockBuilder(Attribute::class) - ->setMethods(['getUsedAttributes', 'getAttributeId', '__wakeup']) + $this->magentoObject = $this->getMockBuilder(\Magento\Framework\DataObject::class) + ->setMethods(['getId']) ->disableOriginalConstructor() ->getMock(); $this->model = $helper->getObject( \Magento\ConfigurableProduct\Model\Entity\Product\Attribute\Group\AttributeMapper\Plugin::class, - [ - 'registry' => $this->registry, - 'attributeFactory' => $this->attributeFactory, - 'setId' => '10', - ] + ['registry' => $this->registry, 'attributeFactory' => $this->attributeFactory] ); } - public function testBeforeMap() + public function testAroundMap() { - $this->registry->expects(static::once())->method('registry') - ->with('current_attribute_set') - ->willReturn($this->magentoObject); - $this->magentoObject->expects(static::once())->method('getId')->willReturn('10'); + $attrSetId = 333; + $expected = ['is_configurable' => 1]; - $this->model->beforeMap($this->attributeMapper); - } + /** @var \PHPUnit_Framework_MockObject_MockObject $attributeMapper */ + $attributeMapper = $this->getMockBuilder( + \Magento\Catalog\Model\Entity\Product\Attribute\Group\AttributeMapperInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); - public function testAfterMap() - { - $attrSetId = '10'; - $expected = ['is_configurable' => 1]; + /** @var \Magento\Eav\Model\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject $attribute */ + $attribute = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class) + ->disableOriginalConstructor() + ->getMock(); + + $proceed = function (Attribute $attribute) { + return []; + }; + + $this->attributeFactory->expects($this->once())->method('create') + ->will($this->returnValue($this->attribute)); + + $this->attribute->expects($this->once())->method('getUsedAttributes') + ->with($this->equalTo($attrSetId)) + ->will($this->returnValue([$attrSetId])); - $this->attributeFactory->expects(static::once())->method('create') - ->willReturn($this->attribute); + $attribute->expects($this->once())->method('getAttributeId') + ->will($this->returnValue($attrSetId)); - $this->attribute->expects(static::once())->method('getUsedAttributes') - ->with($attrSetId) - ->willReturn([$attrSetId]); + $this->registry->expects($this->once())->method('registry') + ->with($this->equalTo('current_attribute_set')) + ->will($this->returnValue($this->magentoObject)); - $this->attribute->expects(static::once())->method('getAttributeId') - ->willReturn($attrSetId); + $this->magentoObject->expects($this->once())->method('getId')->will($this->returnValue($attrSetId)); - $result = $this->model->afterMap($this->attributeMapper, [], $this->attribute); + $result = $this->model->aroundMap($attributeMapper, $proceed, $attribute); $this->assertEquals($expected, $result); } } diff --git a/app/code/Magento/Store/App/Action/Plugin/Context.php b/app/code/Magento/Store/App/Action/Plugin/Context.php index e56b301733c..992ed9fa79c 100644 --- a/app/code/Magento/Store/App/Action/Plugin/Context.php +++ b/app/code/Magento/Store/App/Action/Plugin/Context.php @@ -11,6 +11,7 @@ use Magento\Framework\Phrase; use Magento\Store\Api\StoreCookieManagerInterface; use Magento\Store\Api\StoreResolverInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\Action\AbstractAction; /** * Class ContextPlugin @@ -64,17 +65,12 @@ class Context } /** - * @param \Magento\Framework\App\ActionInterface $subject - * @param callable $proceed - * @param \Magento\Framework\App\RequestInterface $request - * @return mixed + * @param AbstractAction $subject + * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDispatch( - \Magento\Framework\App\ActionInterface $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request - ) { + public function beforeDispatch(AbstractAction $subject) + { /** @var \Magento\Store\Model\Store $defaultStore */ $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); @@ -103,6 +99,5 @@ class Context $this->session->getCurrencyCode() ?: $currentStore->getDefaultCurrencyCode(), $defaultStore->getDefaultCurrencyCode() ); - return $proceed($request); } } diff --git a/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php b/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php index 56a7157e700..572000a8918 100644 --- a/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php +++ b/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php @@ -23,24 +23,17 @@ class StoreCheck } /** - * @param \Magento\Framework\App\ActionInterface $subject - * @param callable $proceed - * @param \Magento\Framework\App\RequestInterface $request - * - * @return \Magento\Framework\App\ResponseInterface + * @param \Magento\Framework\App\Action\AbstractAction $subject + * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @throws \Magento\Framework\Exception\State\InitException */ - public function aroundDispatch( - \Magento\Framework\App\ActionInterface $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request - ) { + public function beforeDispatch(\Magento\Framework\App\Action\AbstractAction $subject) + { if (!$this->_storeManager->getStore()->isActive()) { throw new \Magento\Framework\Exception\State\InitException( __('Current store is not active.') ); } - return $proceed($request); } } diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php index 32aeb0b5151..4b88f275ee2 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php @@ -3,14 +3,12 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\Store\Test\Unit\App\Action\Plugin; use Magento\Framework\App\Http\Context; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\Action\AbstractAction; /** * Class ContextPluginTest @@ -69,40 +67,30 @@ class ContextTest extends \PHPUnit_Framework_TestCase protected $websiteMock; /** - * @var \Closure - */ - protected $closureMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var AbstractAction|\PHPUnit_Framework_MockObject_MockObject */ protected $subjectMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - /** * Set up */ protected function setUp() { - $this->sessionMock = $this->getMock( + $this->sessionMock = $this->getMock( \Magento\Framework\Session\Generic::class, ['getCurrencyCode'], [], '', false ); - $this->httpContextMock = $this->getMock( + $this->httpContextMock = $this->getMock( \Magento\Framework\App\Http\Context::class, [], [], '', false ); - $this->httpRequestMock = $this->getMock( + $this->httpRequestMock = $this->getMock( \Magento\Framework\App\Request\Http::class, ['getParam'], [], @@ -111,38 +99,30 @@ class ContextTest extends \PHPUnit_Framework_TestCase ); $this->storeManager = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); $this->storeCookieManager = $this->getMock(\Magento\Store\Api\StoreCookieManagerInterface::class); - $this->storeMock = $this->getMock( + $this->storeMock = $this->getMock( \Magento\Store\Model\Store::class, [], [], '', false ); - $this->currentStoreMock = $this->getMock( + $this->currentStoreMock = $this->getMock( \Magento\Store\Model\Store::class, [], [], '', false ); - $this->websiteMock = $this->getMock( + $this->websiteMock = $this->getMock( \Magento\Store\Model\Website::class, ['getDefaultStore', '__wakeup'], [], '', false ); - $this->closureMock = function () { - return 'ExpectedValue'; - }; - $this->subjectMock = $this->getMock( - \Magento\Framework\App\Action\Action::class, - [], - [], - '', - false - ); - $this->requestMock = $this->getMock(\Magento\Framework\App\RequestInterface::class); + $this->subjectMock = $this->getMockBuilder(AbstractAction::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); $this->plugin = (new ObjectManager($this))->getObject(\Magento\Store\App\Action\Plugin\Context::class, [ @@ -205,10 +185,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('setValue') ->with(Context::CONTEXT_CURRENCY, self::CURRENCY_SESSION, self::CURRENCY_DEFAULT); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock); } public function testDispatchCurrentStoreCurrency() @@ -241,10 +218,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('setValue') ->with(Context::CONTEXT_CURRENCY, self::CURRENCY_CURRENT_STORE, self::CURRENCY_DEFAULT); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock); } public function testDispatchStoreParameterIsArray() @@ -284,11 +258,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('setValue') ->with(Context::CONTEXT_CURRENCY, self::CURRENCY_CURRENT_STORE, self::CURRENCY_DEFAULT); - $result = $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock); - $this->assertEquals( - 'ExpectedValue', - $result - ); + $this->plugin->beforeDispatch($this->subjectMock); } /** @@ -318,6 +288,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('getParam') ->with($this->equalTo('___store')) ->will($this->returnValue($store)); - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock); + $this->plugin->beforeDispatch($this->subjectMock); } } diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php index 1170377a6b2..bb63674b3c1 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php @@ -3,9 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\Store\Test\Unit\App\Action\Plugin; class StoreCheckTest extends \PHPUnit_Framework_TestCase @@ -26,20 +23,10 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase protected $_storeMock; /** - * @var \Closure - */ - protected $closureMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\App\Action\AbstractAction|\PHPUnit_Framework_MockObject_MockObject */ protected $subjectMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $requestMock; - protected function setUp() { $this->_storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); @@ -51,11 +38,9 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase )->will( $this->returnValue($this->_storeMock) ); - $this->subjectMock = $this->getMock(\Magento\Framework\App\Action\Action::class, [], [], '', false); - $this->closureMock = function () { - return 'Expected'; - }; - $this->requestMock = $this->getMock(\Magento\Framework\App\RequestInterface::class); + $this->subjectMock = $this->getMockBuilder(\Magento\Framework\App\Action\AbstractAction::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); $this->_plugin = new \Magento\Store\App\Action\Plugin\StoreCheck($this->_storeManagerMock); } @@ -67,19 +52,13 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase public function testAroundDispatchWhenStoreNotActive() { $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(false)); - $this->assertEquals( - 'Expected', - $this->_plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->_plugin->beforeDispatch($this->subjectMock); } public function testAroundDispatchWhenStoreIsActive() { $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(true)); - $this->assertEquals( - 'Expected', - $this->_plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->_plugin->beforeDispatch($this->subjectMock); } } -- GitLab From 2968f82368b2f5bf7e6c98f36cec1e34d0cf2ba2 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 17:18:03 +0300 Subject: [PATCH 453/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../ResourceModel/Product/Link/RelationPersisterTest.php | 4 +++- .../Model/ResourceModel/Order/Plugin/AuthorizationTest.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php index eb78d1d7219..4eded50bcf0 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php @@ -107,7 +107,9 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase $subject, $this->object->aroundDeleteProductLink( $subject, - function() use ($subject) { return $subject; }, + function () use ($subject) { + return $subject; + }, 155 ) ); diff --git a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php index 81fcab88697..eeee0b2b910 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Plugin/AuthorizationTest.php @@ -88,4 +88,4 @@ class AuthorizationTest extends \PHPUnit_Framework_TestCase ->willReturn(1); $this->plugin->afterLoad($this->subjectMock, $this->subjectMock, $this->orderMock); } -} \ No newline at end of file +} -- GitLab From dd4ce5d6d9f029f9b3f280505a2f28401b440b40 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 17:20:17 +0300 Subject: [PATCH 454/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Test/Unit/Model/Category/Plugin/Category/RemoveTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php index 73f03ed3f9a..ba9b2c9fbd2 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php @@ -58,7 +58,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase public function testAroundDelete() { $closureSubject = $this->subjectMock; - $proceed = function (CategoryInterface $category) use ($closureSubject) { + $proceed = function () use ($closureSubject) { return $closureSubject; }; $plugin = $this->objectManager->getObject( -- GitLab From 9515999f75fc728084079b8aae7ccc784cd8c1f3 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Wed, 17 Aug 2016 13:05:12 +0300 Subject: [PATCH 455/838] MAGETWO-54866: Validation message displayed all the time --- .../Theme/view/frontend/web/js/view/messages.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/view/frontend/web/js/view/messages.js b/app/code/Magento/Theme/view/frontend/web/js/view/messages.js index 2969fdedd7d..48507343fe2 100644 --- a/app/code/Magento/Theme/view/frontend/web/js/view/messages.js +++ b/app/code/Magento/Theme/view/frontend/web/js/view/messages.js @@ -15,11 +15,23 @@ define([ cookieMessages: [], messages: [] }, + + /** + * Extends Component object by storage observable messages. + */ initialize: function () { this._super(); this.cookieMessages = $.cookieStorage.get('mage-messages'); - this.messages = customerData.get('messages').extend({disposableCustomerData: 'messages'}); + this.messages = customerData.get('messages').extend({ + disposableCustomerData: 'messages' + }); + + // Force to clean obsolete messages + if (!_.isEmpty(this.messages().messages)) { + customerData.set('messages', {}); + } + $.cookieStorage.setConf({path: '/', expires: -1}).set('mage-messages', null); } }); -- GitLab From 58efc8963c2f571d35e7f6b7ff80f4a259edd8b0 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 17 Aug 2016 17:47:16 +0300 Subject: [PATCH 456/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Url/Plugin/RouteParamsResolverTest.php | 43 ++++--------------- .../Store/Url/Plugin/RouteParamsResolver.php | 9 ++-- 2 files changed, 11 insertions(+), 41 deletions(-) diff --git a/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php b/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php index b2c5a972734..959f9efd033 100644 --- a/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php +++ b/app/code/Magento/Store/Test/Unit/Url/Plugin/RouteParamsResolverTest.php @@ -39,10 +39,7 @@ class RouteParamsResolverTest extends \PHPUnit_Framework_TestCase ); } - /** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function testAroundSetRouteParamsScopeInParams() + public function testBeforeSetRouteParamsScopeInParams() { $storeCode = 'custom_store'; $this->scopeConfigMock @@ -66,20 +63,13 @@ class RouteParamsResolverTest extends \PHPUnit_Framework_TestCase $this->queryParamsResolverMock->expects($this->once())->method('setQueryParam')->with('___store', $storeCode); - $this->model->aroundSetRouteParams( + $this->model->beforeSetRouteParams( $routeParamsResolverMock, - function ($data, $unsetOldParams) { - $this->assertArrayNotHasKey('_scope_to_url', $data, 'This data item should have been unset.'); - $this->assertArrayNotHasKey('_scope', $data, 'This data item should have been unset.'); - }, $data ); } - /** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function testAroundSetRouteParamsScopeUseStoreInUrl() + public function testBeforeSetRouteParamsScopeUseStoreInUrl() { $storeCode = 'custom_store'; $this->scopeConfigMock @@ -103,20 +93,13 @@ class RouteParamsResolverTest extends \PHPUnit_Framework_TestCase $this->queryParamsResolverMock->expects($this->never())->method('setQueryParam'); - $this->model->aroundSetRouteParams( + $this->model->beforeSetRouteParams( $routeParamsResolverMock, - function ($data, $unsetOldParams) { - $this->assertArrayNotHasKey('_scope_to_url', $data, 'This data item should have been unset.'); - $this->assertArrayNotHasKey('_scope', $data, 'This data item should have been unset.'); - }, $data ); } - /** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function testAroundSetRouteParamsSingleStore() + public function testBeforeSetRouteParamsSingleStore() { $storeCode = 'custom_store'; $this->scopeConfigMock @@ -140,20 +123,13 @@ class RouteParamsResolverTest extends \PHPUnit_Framework_TestCase $this->queryParamsResolverMock->expects($this->never())->method('setQueryParam'); - $this->model->aroundSetRouteParams( + $this->model->beforeSetRouteParams( $routeParamsResolverMock, - function ($data, $unsetOldParams) { - $this->assertArrayNotHasKey('_scope_to_url', $data, 'This data item should have been unset.'); - $this->assertArrayNotHasKey('_scope', $data, 'This data item should have been unset.'); - }, $data ); } - /** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - public function testAroundSetRouteParamsNoScopeInParams() + public function testBeforeSetRouteParamsNoScopeInParams() { $storeCode = 'custom_store'; $this->scopeConfigMock @@ -185,11 +161,8 @@ class RouteParamsResolverTest extends \PHPUnit_Framework_TestCase $this->queryParamsResolverMock->expects($this->once())->method('setQueryParam')->with('___store', $storeCode); - $this->model->aroundSetRouteParams( + $this->model->beforeSetRouteParams( $routeParamsResolverMock, - function ($data, $unsetOldParams) { - $this->assertArrayNotHasKey('_scope_to_url', $data, 'This data item should have been unset.'); - }, $data ); } diff --git a/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php b/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php index 4435dfe108c..8ef0420a23c 100644 --- a/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php +++ b/app/code/Magento/Store/Url/Plugin/RouteParamsResolver.php @@ -49,15 +49,12 @@ class RouteParamsResolver * Process scope query parameters. * * @param \Magento\Framework\Url\RouteParamsResolver $subject - * @param callable $proceed * @param array $data * @param bool $unsetOldParams - * @return \Magento\Framework\Url\RouteParamsResolver - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @return array */ - public function aroundSetRouteParams( + public function beforeSetRouteParams( \Magento\Framework\Url\RouteParamsResolver $subject, - \Closure $proceed, array $data, $unsetOldParams = true ) { @@ -78,6 +75,6 @@ class RouteParamsResolver } unset($data['_scope_to_url']); - return $proceed($data, $unsetOldParams); + return [$data, $unsetOldParams]; } } -- GitLab From 738eaba7dcbe33aa34466e6e155e9d330cb7ed31 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Wed, 17 Aug 2016 17:50:20 +0300 Subject: [PATCH 457/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../PageCache/Model/App/FrontController/VarnishPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php b/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php index d2a5dbf4942..08b68447c9d 100644 --- a/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php +++ b/app/code/Magento/PageCache/Model/App/FrontController/VarnishPlugin.php @@ -50,7 +50,7 @@ class VarnishPlugin * * @param FrontControllerInterface $subject * @param ResponseInterface|ResultInterface $result - * @return ResponseHttp|ResultInterface|false + * @return ResponseHttp|ResultInterface * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ -- GitLab From 8b1ae9bd8f01aff00a69f1b2ebd0db2bf1c8c461 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Wed, 17 Aug 2016 17:51:06 +0300 Subject: [PATCH 458/838] MAGETWO-56703: Around plugins refactoring: stabilize code --- .../Test/Unit/Model/Category/Plugin/Category/RemoveTest.php | 2 +- .../ConfigurableProduct/Model/Product/Validator/Plugin.php | 6 ++++-- .../PageCache/Model/Controller/Result/BuiltinPlugin.php | 3 +-- .../Unit/Model/App/FrontController/VarnishPluginTest.php | 3 +++ .../Test/Unit/Model/Controller/Result/BuiltinPluginTest.php | 3 +++ .../Test/Unit/Model/Controller/Result/VarnishPluginTest.php | 3 +++ 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php index ba9b2c9fbd2..04dcffb4f8e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php @@ -61,7 +61,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase $proceed = function () use ($closureSubject) { return $closureSubject; }; - $plugin = $this->objectManager->getObject( + $plugin = $this->objectManager->getObject( Remove::class, [ 'urlPersist' => $this->urlPersistMock, diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php index 7fc383b466f..c8f525cd462 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php @@ -5,12 +5,12 @@ */ namespace Magento\ConfigurableProduct\Model\Product\Validator; -use Closure; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ProductFactory; use Magento\Framework\App\RequestInterface; use Magento\Framework\Event\Manager; use Magento\Framework\Json\Helper\Data; +use Magento\Framework\DataObject; /** * Configurable product validation @@ -51,13 +51,15 @@ class Plugin * @param Product\Validator $subject * @param Product $product * @param RequestInterface $request + * @param DataObject $response * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function beforeValidate( \Magento\Catalog\Model\Product\Validator $subject, \Magento\Catalog\Model\Product $product, - \Magento\Framework\App\RequestInterface $request + \Magento\Framework\App\RequestInterface $request, + DataObject $response ) { if ($request->has('attributes')) { $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE); diff --git a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php index d4ce523da0a..5900a37bad6 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php @@ -67,8 +67,7 @@ class BuiltinPlugin { $usePlugin = $this->registry->registry('use_page_cache_plugin'); - if (!$usePlugin || !$this->config->isEnabled() || $this->config->getType() != Config::BUILT_IN) - { + if (!$usePlugin || !$this->config->isEnabled() || $this->config->getType() != Config::BUILT_IN) { return $result; } diff --git a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php index 486e1f2e04a..a9b0e10307a 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/VarnishPluginTest.php @@ -14,6 +14,9 @@ use Magento\Framework\App\FrontControllerInterface; use Magento\Framework\App\Response\Http as ResponseHttp; use Magento\Framework\Controller\ResultInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class VarnishPluginTest extends \PHPUnit_Framework_TestCase { /** diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php index d735484844f..f0ba7b22dad 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/BuiltinPluginTest.php @@ -16,6 +16,9 @@ use Magento\Framework\App\Response\Http as ResponseHttp; use Zend\Http\Header\HeaderInterface as HttpHeaderInterface; use Magento\PageCache\Model\Cache\Type as CacheType; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class BuiltinPluginTest extends \PHPUnit_Framework_TestCase { /** diff --git a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php index d280a3d7d8c..a54dc5bacb5 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/Controller/Result/VarnishPluginTest.php @@ -14,6 +14,9 @@ use Magento\Framework\Registry; use Magento\Framework\Controller\ResultInterface; use Magento\Framework\App\Response\Http as ResponseHttp; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class VarnishPluginTest extends \PHPUnit_Framework_TestCase { /** -- GitLab From ba8a4ce4c67f282fade9e0596834f3550e5b6a5f Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 17 Aug 2016 18:08:50 +0300 Subject: [PATCH 459/838] MAGETWO-56984: Notification messages area. Dismiss controls. --- .../view/adminhtml/web/js/grid/columns/message.js | 4 ++-- .../Magento_AdminNotification/web/css/source/_module.less | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js index e5778f17fd1..1014ba56340 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js @@ -16,9 +16,9 @@ define([ message: true }, statusMap: { - 0: 'info', + 0: 'success', 1: 'progress', - 2: 'success', + 2: 'info', 3: 'error' } }, diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index cad2321d3ce..69aeb0ef930 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -44,6 +44,10 @@ } .action-menu-item { + &.action-close { + float: right; + } + display: inline-block; vertical-align: top; padding: @message-system-short-message__padding-vertical 0 0; -- GitLab From 61fa5f048464ceac285ee43b17ecf1a6a3d2ea76 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 19:07:13 +0300 Subject: [PATCH 460/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/ShipmentFactory.php | 20 +++++++++++++++++-- .../Model/Order/ShipmentQuantityValidator.php | 10 ++-------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php index db0d8a02419..a8839c75375 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentFactory.php @@ -108,7 +108,7 @@ class ShipmentFactory $qty = $bundleSelectionAttributes['qty'] * $items[$orderItem->getParentItemId()]; $qty = min($qty, $orderItem->getSimpleQtyToShip()); - $item->setQty($qty); + $item->setQty($this->castQty($orderItem, $qty)); $shipment->addItem($item); continue; @@ -131,7 +131,7 @@ class ShipmentFactory $totalQty += $qty; - $item->setQty($qty); + $item->setQty($this->castQty($orderItem, $qty)); $shipment->addItem($item); } return $shipment->setTotalQty($totalQty); @@ -215,4 +215,20 @@ class ShipmentFactory return $item->getQtyToShip() > 0; } } + + /** + * @param Item $item + * @param string|int|float $qty + * @return float|int + */ + private function castQty(\Magento\Sales\Model\Order\Item $item, $qty) + { + if ($item->getIsQtyDecimal()) { + $qty = (double)$qty; + } else { + $qty = (int)$qty; + } + + return $qty > 0 ? $qty : 0; + } } diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index e5b7d5d52b6..58870793a87 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -70,14 +70,8 @@ class ShipmentQuantityValidator implements ValidatorInterface if ($orderItem === null) { return [__('We can not found item "%1" in order.', $item->getOrderItemId())]; } - if ($orderItem->getIsQtyDecimal()) { - $qty = (double)$item->getQty(); - } else { - $qty = (int)$item->getQty(); - } - $qty = $qty > 0 ? $qty : 0; - if (!$this->isQtyAvailable($orderItem, $qty)) { + if (!$this->isQtyAvailable($orderItem, $item->getQty())) { $messages[] =__('We found an invalid quantity to ship for item "%1".', $item->getName()); } @@ -107,6 +101,6 @@ class ShipmentQuantityValidator implements ValidatorInterface */ private function isQtyAvailable(Item $orderItem, $qty) { - return $qty !== 0 && ($qty <= $orderItem->getQtyToShip() || $orderItem->isDummy(true)); + return $qty <= $orderItem->getQtyToShip() || $orderItem->isDummy(true); } } -- GitLab From c9ea7cdc52f362f5e3c633351f9e6bd52eed3d44 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Aug 2016 19:22:44 +0300 Subject: [PATCH 461/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage - Added parameter to before plugins; --- .../Magento/Store/App/Action/Plugin/Context.php | 4 +++- .../Store/App/Action/Plugin/StoreCheck.php | 7 +++++-- .../Test/Unit/App/Action/Plugin/ContextTest.php | 15 +++++++++++---- .../Unit/App/Action/Plugin/StoreCheckTest.php | 10 ++++++++-- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/App/Action/Plugin/Context.php b/app/code/Magento/Store/App/Action/Plugin/Context.php index 992ed9fa79c..267d7cd5c22 100644 --- a/app/code/Magento/Store/App/Action/Plugin/Context.php +++ b/app/code/Magento/Store/App/Action/Plugin/Context.php @@ -12,6 +12,7 @@ use Magento\Store\Api\StoreCookieManagerInterface; use Magento\Store\Api\StoreResolverInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Action\AbstractAction; +use Magento\Framework\App\RequestInterface; /** * Class ContextPlugin @@ -66,10 +67,11 @@ class Context /** * @param AbstractAction $subject + * @param RequestInterface $request * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function beforeDispatch(AbstractAction $subject) + public function beforeDispatch(AbstractAction $subject, RequestInterface $request) { /** @var \Magento\Store\Model\Store $defaultStore */ $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); diff --git a/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php b/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php index 572000a8918..fcb93162207 100644 --- a/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php +++ b/app/code/Magento/Store/App/Action/Plugin/StoreCheck.php @@ -24,12 +24,15 @@ class StoreCheck /** * @param \Magento\Framework\App\Action\AbstractAction $subject + * @param \Magento\Framework\App\RequestInterface $request * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @throws \Magento\Framework\Exception\State\InitException */ - public function beforeDispatch(\Magento\Framework\App\Action\AbstractAction $subject) - { + public function beforeDispatch( + \Magento\Framework\App\Action\AbstractAction $subject, + \Magento\Framework\App\RequestInterface $request + ) { if (!$this->_storeManager->getStore()->isActive()) { throw new \Magento\Framework\Exception\State\InitException( __('Current store is not active.') diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php index 4b88f275ee2..9ecbb897b4b 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php @@ -9,6 +9,7 @@ use Magento\Framework\App\Http\Context; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Action\AbstractAction; +use Magento\Framework\App\RequestInterface; /** * Class ContextPluginTest @@ -71,6 +72,11 @@ class ContextTest extends \PHPUnit_Framework_TestCase */ protected $subjectMock; + /** + * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $requestMock; + /** * Set up */ @@ -120,6 +126,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase '', false ); + $this->requestMock = $this->getMock(RequestInterface::class); $this->subjectMock = $this->getMockBuilder(AbstractAction::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -185,7 +192,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('setValue') ->with(Context::CONTEXT_CURRENCY, self::CURRENCY_SESSION, self::CURRENCY_DEFAULT); - $this->plugin->beforeDispatch($this->subjectMock); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } public function testDispatchCurrentStoreCurrency() @@ -218,7 +225,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('setValue') ->with(Context::CONTEXT_CURRENCY, self::CURRENCY_CURRENT_STORE, self::CURRENCY_DEFAULT); - $this->plugin->beforeDispatch($this->subjectMock); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } public function testDispatchStoreParameterIsArray() @@ -258,7 +265,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('setValue') ->with(Context::CONTEXT_CURRENCY, self::CURRENCY_CURRENT_STORE, self::CURRENCY_DEFAULT); - $this->plugin->beforeDispatch($this->subjectMock); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } /** @@ -288,6 +295,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('getParam') ->with($this->equalTo('___store')) ->will($this->returnValue($store)); - $this->plugin->beforeDispatch($this->subjectMock); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } } diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php index bb63674b3c1..33be7fd8251 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php @@ -27,6 +27,11 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase */ protected $subjectMock; + /** + * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $requestMock; + protected function setUp() { $this->_storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); @@ -38,6 +43,7 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase )->will( $this->returnValue($this->_storeMock) ); + $this->requestMock = $this->getMock(\Magento\Framework\App\RequestInterface::class); $this->subjectMock = $this->getMockBuilder(\Magento\Framework\App\Action\AbstractAction::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -52,13 +58,13 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase public function testAroundDispatchWhenStoreNotActive() { $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(false)); - $this->_plugin->beforeDispatch($this->subjectMock); + $this->_plugin->beforeDispatch($this->subjectMock, $this->requestMock); } public function testAroundDispatchWhenStoreIsActive() { $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(true)); - $this->_plugin->beforeDispatch($this->subjectMock); + $this->_plugin->beforeDispatch($this->subjectMock, $this->requestMock); } } -- GitLab From 9700f147f32bb123cdb639d4f7230e2b80f83849 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 19:24:26 +0300 Subject: [PATCH 462/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Model/Order/ShipmentQuantityValidator.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index 58870793a87..efaf861ae03 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -51,10 +51,23 @@ class ShipmentQuantityValidator implements ValidatorInterface $messages = []; $order = $this->orderRepository->get($entity->getOrderId()); - foreach ($entity->getItems() as $shipmentItem) { - $messages = array_merge($messages, $this->validateShipmentItem($shipmentItem, $order)); - } + $totalQuantity = 0; + foreach ($entity->getItems() as $item) { + $orderItem = $this->getOrderItemById($order, $item->getOrderItemId()); + if ($orderItem === null) { + $messages[] = __('We can not found item "%1" in order.', $item->getOrderItemId()); + continue; + } + if (!$this->isQtyAvailable($orderItem, $item->getQty())) { + $messages[] =__('We found an invalid quantity to ship for item "%1".', $item->getName()); + } else { + $totalQuantity += $item->getQty(); + } + } + if ($totalQuantity <= 0) { + $messages[] = __('You can\'t create a shipment without products.'); + } return $messages; } -- GitLab From 1ec50f1f03f89f87e670c6189e7261ef3d79647f Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Wed, 17 Aug 2016 19:25:02 +0300 Subject: [PATCH 463/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Model/Order/ShipmentQuantityValidator.php | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index efaf861ae03..bce62402ba3 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -71,26 +71,6 @@ class ShipmentQuantityValidator implements ValidatorInterface return $messages; } - /** - * @param ShipmentItemInterface $item - * @param OrderInterface $order - * @return string[] - */ - public function validateShipmentItem(ShipmentItemInterface $item, OrderInterface $order) - { - $messages = []; - $orderItem = $this->getOrderItemById($order, $item->getOrderItemId()); - if ($orderItem === null) { - return [__('We can not found item "%1" in order.', $item->getOrderItemId())]; - } - - if (!$this->isQtyAvailable($orderItem, $item->getQty())) { - $messages[] =__('We found an invalid quantity to ship for item "%1".', $item->getName()); - } - - return $messages; - } - /** * @param OrderInterface $order * @param int $id -- GitLab From 1edd6c40a378f126c1d2f165bdc96deb446f124f Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Wed, 17 Aug 2016 11:27:14 -0500 Subject: [PATCH 464/838] MAGETWO-55950: Automate Create new Email Template test - fixing static code analysis comments. --- .../Block/Adminhtml/Template/Edit/TemplateForm.php | 13 +++++++------ .../AssertEmailTemplateSuccessSaveMessage.php | 5 ++++- .../Test/TestCase/CreateEmailTemplateEntityTest.php | 12 ++++++------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php index 4fcdf35385f..110fdada800 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php @@ -9,18 +9,19 @@ use Magento\Mtf\Block\Form; use Magento\Mtf\Client\Locator; /** - Click Load button in Email template form. - this class needs to be created becuase we need a customized click on the 'Load' button, its not a standard click -*/ + * Click Load button in Email template form. + * this class needs to be created because we need a customized click on the 'Load' button, its not a standard click + */ class TemplateForm extends Form { private $loadButton = "#load"; /** - * + * @return void */ - public function clickLoadTemplate() { + public function clickLoadTemplate() + { $element = $this->_rootElement->find($this->loadButton, Locator::SELECTOR_CSS); // locate the Load button $element->click(); // click the load button } -} \ No newline at end of file +} diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php index 1f7b25001ff..d949ba70039 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php @@ -1,5 +1,8 @@ <?php - +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Email\Test\Constraint; use Magento\Email\Test\Page\Adminhtml\EmailTemplateIndex; diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php index e52daf9b6e0..a571ba6957e 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php @@ -50,16 +50,16 @@ class CreateEmailTemplateEntityTest extends Injectable /** * Inject Email template pages. * - * @param EmailTemplateIndex $EmailTemplateIndex - * @param EmailTemplateNew $EmailTemplateNew + * @param EmailTemplateIndex $emailTemplateIndex + * @param EmailTemplateNew $emailTemplateNew * @return void */ public function __inject( - EmailTemplateIndex $EmailTemplateIndex, - EmailTemplateNew $EmailTemplateNew + EmailTemplateIndex $emailTemplateIndex, + EmailTemplateNew $emailTemplateNew ) { - $this->emailTemplateIndex = $EmailTemplateIndex; - $this->emailTemplateNew = $EmailTemplateNew; + $this->emailTemplateIndex = $emailTemplateIndex; + $this->emailTemplateNew = $emailTemplateNew; } /** -- GitLab From 16cd4fd2dad2ffec1c3c2aabb4c27d9d3d1a2bd4 Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Wed, 17 Aug 2016 11:58:50 -0500 Subject: [PATCH 465/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - fixing code styles. --- .../Config/Test/Block/System/Config/AdminForm.php | 10 +++++++--- .../TestCase/VerifyAdminAccountSharingEntityTest.php | 10 ++++++---- .../TestCase/VerifyAdminAccountSharingEntityTest.xml | 6 ++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php index e8c77d23b21..5d395e4efa4 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php @@ -1,4 +1,8 @@ <?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Config\Test\Block\System\Config; @@ -6,9 +10,9 @@ use Magento\Mtf\Block\Form; use Magento\Mtf\Client\Locator; /** - * Admin Security edit form in admin. - */ -/* this class needs to be created becuase we need to check for the availability of Admin account sharing settings, This is not possible using the form block class only + * Admin Security form in admin configurations. + * + * this class needs to be created becuase we need to check for the availability of Admin account sharing settings, This is not possible using the form block class only */ class AdminForm extends Form { diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php index 4f64d5a765d..4a77356e742 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php @@ -1,10 +1,13 @@ <?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Config\Test\TestCase; use Magento\Mtf\TestCase\Injectable; use Magento\Config\Test\Page\Adminhtml\AdminAccountSharing; -use Magento\Config\Test\Fixture\ConfigDataWithAdminAccountSharing; /** * Steps: @@ -49,12 +52,11 @@ class VerifyAdminAccountSharingEntityTest extends Injectable /** * Create Verify Admin Account Sharing test. * - * @param ConfigDataWithAdminAccountSharing $ConfigDataWithAdminAccountSharing * @return void */ - public function test(ConfigDataWithAdminAccountSharing $ConfigDataWithAdminAccountSharing) + public function test() { $this->adminAccountSharing->open(); } -} \ No newline at end of file +} diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml index db8ed432f09..4f359b99339 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml @@ -1,4 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\Config\Test\TestCase\VerifyAdminAccountSharingEntityTest" summary="Verify admin account sharing option availability" ticketId="MAGETWO-47822"> <variation name="VerifyAdminAccountSharingEntityTestVariation1" summary="Verify Admin Account Sharing is available by default"> -- GitLab From 242cb753bc3b8bf8aa079682db6cae5672245ce2 Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Wed, 17 Aug 2016 12:01:36 -0500 Subject: [PATCH 466/838] MAGETWO-55950: Automate Create new Email Template test - fixing static code analysis comments. --- .../Constraint/AssertEmailTemplateSuccessSaveMessage.php | 2 +- .../Email/Test/TestCase/CreateEmailTemplateEntityTest.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php index d949ba70039..4fbba15df27 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Constraint/AssertEmailTemplateSuccessSaveMessage.php @@ -39,4 +39,4 @@ class AssertEmailTemplateSuccessSaveMessage extends AbstractConstraint { return 'Assert that success message is displayed.'; } -} \ No newline at end of file +} diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php index a571ba6957e..dc86b647975 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/TestCase/CreateEmailTemplateEntityTest.php @@ -63,15 +63,15 @@ class CreateEmailTemplateEntityTest extends Injectable } /** - * @param EmailTemplate $EmailTemplate + * @param EmailTemplate $emailTemplate */ - public function test(EmailTemplate $EmailTemplate) + public function test(EmailTemplate $emailTemplate) { $this->emailTemplateIndex->open(); $this->emailTemplateIndex->getPageActionsBlock()->addNew(); - $this->emailTemplateNew->getTemplateForm()->fill($EmailTemplate); + $this->emailTemplateNew->getTemplateForm()->fill($emailTemplate); $this->emailTemplateNew->getTemplateForm()->clickLoadTemplate(); $this->emailTemplateNew->getFormPageActions()->save(); } -} \ No newline at end of file +} -- GitLab From 6fdda18b7f131d9d9e6d027809610c68f86b45ce Mon Sep 17 00:00:00 2001 From: Andrii Lugovyi <alugovyi@magento.com> Date: Tue, 16 Aug 2016 19:55:30 +0300 Subject: [PATCH 467/838] MAGETWO-56586: Port MAGETWO-55862 to develop - fix static --- .../Magento/Test/Legacy/ModuleDBChangeTest.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php index e0628abec03..4029454ee52 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/ModuleDBChangeTest.php @@ -1,18 +1,17 @@ <?php /** - * - * Scan source code for DB schema or data updates for patch releases in non-actual branches - * Backwards compatibility test - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Test\Legacy; +/** + * Scan source code for DB schema or data updates for patch releases in non-actual branches + * Backwards compatibility test + */ +namespace Magento\Test\Legacy; class ModuleDBChangeTest extends \PHPUnit_Framework_TestCase { - /** * @var string */ -- GitLab From 6faecd9b97e1b31f319b53b08bf5ea1e55fd628f Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 17 Aug 2016 20:23:51 +0300 Subject: [PATCH 468/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Magento/Tax/Model/App/Action/ContextPlugin.php | 10 ++-------- .../Tax/Model/Quote/GrandTotalDetailsPlugin.php | 8 ++++---- .../Tax/Test/Unit/App/Action/ContextPluginTest.php | 6 +----- .../Unit/Model/Quote/GrandTotalDetailsPluginTest.php | 11 +---------- 4 files changed, 8 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index 00dd9ff4cda..03927aed968 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -6,9 +6,6 @@ namespace Magento\Tax\Model\App\Action; -use Magento\Customer\Model\Context; -use Magento\Customer\Model\GroupManagement; - /** * Class ContextPlugin */ @@ -74,21 +71,19 @@ class ContextPlugin /** * @param \Magento\Framework\App\ActionInterface $subject - * @param callable $proceed * @param \Magento\Framework\App\RequestInterface $request * @return mixed * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDispatch( + public function beforeDispatch( \Magento\Framework\App\ActionInterface $subject, - \Closure $proceed, \Magento\Framework\App\RequestInterface $request ) { if (!$this->customerSession->isLoggedIn() || !$this->moduleManager->isEnabled('Magento_PageCache') || !$this->cacheConfig->isEnabled() || !$this->taxHelper->isCatalogPriceDisplayAffectedByTax()) { - return $proceed($request); + return; } $defaultBillingAddress = $this->customerSession->getDefaultTaxBillingAddress(); @@ -107,6 +102,5 @@ class ContextPlugin 0 ); } - return $proceed($request); } } diff --git a/app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php b/app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php index 7964353a74c..a727beef10b 100644 --- a/app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php +++ b/app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php @@ -71,18 +71,18 @@ class GrandTotalDetailsPlugin /** * @param \Magento\Quote\Model\Cart\TotalsConverter $subject - * @param \Closure $proceed + * @param \Magento\Quote\Api\Data\TotalSegmentInterface[] $totalSegments * @param \Magento\Quote\Model\Quote\Address\Total[] $addressTotals + * * @return \Magento\Quote\Api\Data\TotalSegmentInterface[] * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function aroundProcess( + public function afterProcess( \Magento\Quote\Model\Cart\TotalsConverter $subject, - \Closure $proceed, + array $totalSegments, array $addressTotals = [] ) { - $totalSegments = $proceed($addressTotals); if (!array_key_exists($this->code, $addressTotals)) { return $totalSegments; diff --git a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php index 6bf64c33009..58b2b5e6d89 100644 --- a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php @@ -160,11 +160,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $action = $this->objectManager->getObject(\Magento\Framework\App\Test\Unit\Action\Stub\ActionStub::class); $request = $this->getMock(\Magento\Framework\App\Request\Http::class, ['getActionName'], [], '', false); - $expectedResult = 'expectedResult'; - $proceed = function ($request) use ($expectedResult) { - return $expectedResult; - }; - $this->contextPlugin->aroundDispatch($action, $proceed, $request); + $this->contextPlugin->beforeDispatch($action, $request); } } diff --git a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php index 52af1315ba7..82ce962daef 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php @@ -38,11 +38,6 @@ class GrandTotalDetailsPluginTest extends \PHPUnit_Framework_TestCase */ protected $subjectMock; - /** - * @var \Closure|\PHPUnit_Framework_MockObject_MockObject - */ - protected $closureMock; - /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ @@ -211,11 +206,7 @@ class GrandTotalDetailsPluginTest extends \PHPUnit_Framework_TestCase 'tax' => $taxSegmentMock, ]; - $this->closureMock = function () use ($totalSegments) { - return $totalSegments; - }; - - $result = $this->model->aroundProcess($this->subjectMock, $this->closureMock, $addressTotals); + $result = $this->model->afterProcess($this->subjectMock, $totalSegments, $addressTotals); $this->assertEquals($totalSegments, $result); } } -- GitLab From b4521fb7e177c383986e34348ffd122b09b29a30 Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Wed, 17 Aug 2016 13:54:37 -0500 Subject: [PATCH 469/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - fixing code styles. --- .../Constraint/AssertAdminAccountSharing.php | 6 ++++- .../VerifyAdminAccountSharingEntityTest.php | 27 +++++++------------ .../VerifyAdminAccountSharingEntityTest.xml | 2 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php index 2bc4d1dcbf8..5d30ab50cf2 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php @@ -1,4 +1,8 @@ <?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Config\Test\Constraint; @@ -31,4 +35,4 @@ class AssertAdminAccountSharing extends AbstractConstraint { return 'Admin account sharing is available is present in in Stores>Configuration>advanced>admin grid.'; } -} \ No newline at end of file +} diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php index 4a77356e742..30928810490 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.php @@ -12,15 +12,11 @@ use Magento\Config\Test\Page\Adminhtml\AdminAccountSharing; /** * Steps: * 1. Log in to Admin. - * 2. Open the Email Templates page. - * 3. Click the "Add New Template" button. - * 4. Select Email Template. - * 5. Click the "Load Template" button. - * 6. Enter Email Template name. - * 7. Verify the email template saved successfully. + * 2. Go to Stores>Configuration>Advanced>admin>Security. + * 3. * 7. Verify admin Acoount Sharing option availability. * - * @group Email_(PS) - * @ZephyrId MAGETWO-17155 + * @group Config_(PS) + * @ZephyrId MAGETWO-47822 */ class VerifyAdminAccountSharingEntityTest extends Injectable { @@ -31,22 +27,19 @@ class VerifyAdminAccountSharingEntityTest extends Injectable /* end tags */ /** - * Email Template Index page. + * Admin account settings page. * - * @var AdminAccountSharing + * @var adminAccountSharing */ private $adminAccountSharing; /** - * Inject synonym pages. - * - * @param $AdminAccountSharing $AdminAccountSharing - * @return void + * @param AdminAccountSharing $adminAccountSharing */ public function __inject( - AdminAccountSharing $AdminAccountSharing + AdminAccountSharing $adminAccountSharing ) { - $this->adminAccountSharing = $AdminAccountSharing; + $this->adminAccountSharing = $adminAccountSharing; } /** @@ -57,6 +50,6 @@ class VerifyAdminAccountSharingEntityTest extends Injectable public function test() { $this->adminAccountSharing->open(); - + sleep(10); } } diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml index 4f359b99339..46b043e6fb5 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Config/Test/TestCase/VerifyAdminAccountSharingEntityTest.xml @@ -11,4 +11,4 @@ <constraint name="Magento\Config\Test\Constraint\AssertAdminAccountSharing" /> </variation> </testCase> - </config> \ No newline at end of file + </config> -- GitLab From ae41d3bc466ea46a3579a85439970ec933e1e4e9 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 17 Aug 2016 14:06:51 -0500 Subject: [PATCH 470/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module --- .../adminhtml/templates/catalog/category/widget/tree.phtml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml index 32c7486d867..5533074de13 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -6,6 +6,7 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Catalog\Block\Adminhtml\Category\Widget\Chooser $block */ ?> <?php $_divId = 'tree' . $block->getId() ?> @@ -43,7 +44,7 @@ Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { if (firstLoad) { <?php if ($block->getNodeClickListener()): ?> - this.addListener('click', <?php echo $block->escapeJs($block->getNodeClickListener()) ?>.createDelegate(this)); + this.addListener('click', <?php echo $block->escapeHtml($block->getNodeClickListener()) ?>.createDelegate(this)); <?php endif; ?> } @@ -158,7 +159,7 @@ jQuery(function() loader: categoryLoader, enableDD: false, containerScroll: true, - rootVisible: '<?php echo $block->escapeJs($block->getRoot()->getIsVisible()) ?>', + rootVisible: '<?php echo (bool) $block->getRoot()->getIsVisible() ?>', useAjax: true, currentNodeId: <?php echo (int) $block->getCategoryId() ?>, addNodeTo: false -- GitLab From 2808b89e60e5fd9ad1d528ca16435d9895031b39 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 17 Aug 2016 14:21:10 -0500 Subject: [PATCH 471/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 - fixing code for code duplication as per code review --- .../Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index a17acb4dea1..af7293ad920 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -540,8 +540,9 @@ class Eav extends AbstractModifier */ private function isProductHasValueForAttribute(ProductAttributeInterface $attribute) { - return (bool)($this->locator->getProduct()->getCustomAttribute($attribute->getAttributeCode()) !== null) - && $this->locator->getProduct()->getCustomAttribute($attribute->getAttributeCode())->getValue(); + /** @var \Magento\Framework\Api\AttributeInterface $attributeCode */ + $attributeCode = $this->locator->getProduct()->getCustomAttribute($attribute->getAttributeCode()); + return (bool)($attributeCode !== null) && $attributeCode->getValue(); } /** -- GitLab From 10ac7a5112b36616cdc29f06a5ed815acb33062f Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 17 Aug 2016 16:18:48 -0500 Subject: [PATCH 472/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 - adding unit test --- .../Product/Form/Modifier/EavTest.php | 207 +++++++++++++++++- .../Product/Form/Modifier/Eav.php | 1 + 2 files changed, 207 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index 10722de41c1..f7ef45563d2 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -9,6 +9,7 @@ use Magento\Catalog\Model\Product\Type; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav; use Magento\Eav\Model\Config; use Magento\Framework\App\RequestInterface; +use Magento\Framework\EntityManager\EventManager; use Magento\Store\Model\StoreManagerInterface; use Magento\Store\Api\Data\StoreInterface; use Magento\Ui\DataProvider\EavValidationRules; @@ -27,11 +28,15 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\Framework\Api\SearchResultsInterface; use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Framework\Api\AttributeInterface; use Magento\Eav\Api\Data\AttributeGroupInterface; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; use Magento\Framework\Currency; use Magento\Framework\Locale\Currency as CurrencyLocale; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\Stdlib\ArrayManager; +use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory as EavAttributeFactory; +use Magento\Framework\Event\ManagerInterface; /** * Class EavTest @@ -157,6 +162,27 @@ class EavTest extends AbstractModifierTest */ protected $currencyLocaleMock; + /** + * @var ProductAttributeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $productAttributeMock; + + /** + * @var ArrayManager|\PHPUnit_Framework_MockObject_MockObject + */ + protected $arrayManagerMock; + + /** + * @var EavAttributeFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eavAttributeFactoryMock; + + /** + * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eventManagerMock; + + /** * @var ObjectManager */ @@ -228,10 +254,24 @@ class EavTest extends AbstractModifierTest $this->searchResultsMock = $this->getMockBuilder(SearchResultsInterface::class) ->getMockForAbstractClass(); $this->eavAttributeMock = $this->getMockBuilder(Attribute::class) - ->setMethods(['getAttributeGroupCode', 'getApplyTo', 'getFrontendInput', 'getAttributeCode']) + ->setMethods(['load', 'getAttributeGroupCode', 'getApplyTo', 'getFrontendInput', 'getAttributeCode']) + ->disableOriginalConstructor() + ->getMock(); + $this->productAttributeMock = $this->getMockBuilder(ProductAttributeInterface::class) + ->getMock(); + $this->arrayManagerMock = $this->getMockBuilder(ArrayManager::class) + ->getMock(); + $this->eavAttributeFactoryMock = $this->getMockBuilder(EavAttributeFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class) ->disableOriginalConstructor() ->getMock(); + $this->eavAttributeFactoryMock->expects($this->any()) + ->method('create') + ->willReturn($this->eavAttributeMock); $this->groupCollectionFactoryMock->expects($this->any()) ->method('create') ->willReturn($this->groupCollectionMock); @@ -277,6 +317,9 @@ class EavTest extends AbstractModifierTest ->disableOriginalConstructor() ->setMethods(['getCurrency']) ->getMock(); + $this->eavAttributeMock->expects($this->any()) + ->method('load') + ->willReturnSelf(); $this->eav =$this->getModel(); $this->objectManager->setBackwardCompatibleProperty( @@ -304,6 +347,9 @@ class EavTest extends AbstractModifierTest 'attributeGroupRepository' => $this->attributeGroupRepositoryMock, 'sortOrderBuilder' => $this->sortOrderBuilderMock, 'attributeRepository' => $this->attributeRepositoryMock, + 'arrayManager' => $this->arrayManagerMock, + 'eavAttributeFactory' => $this->eavAttributeFactoryMock, + '_eventManager' => $this->eventManagerMock ]); } @@ -399,4 +445,163 @@ class EavTest extends AbstractModifierTest $this->assertEquals($sourceData, $this->eav->modifyData([])); } + + /** + * @param int $productId + * @param bool $productRequired + * @param string $attrValue + * @param array $expected + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isProductNew + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isProductHasValueForAttribute + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isShowDefaultValue + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::setupAttributeMeta + * @dataProvider setupAttributeMetaDataProvider + */ + public function testSetupAttributeMetaDefaultAttribute($productId, $productRequired, $attrValue, $expected) + { + $configPath = 'arguments/data/config'; + $groupCode = 'product-details'; + $sortOrder = '0'; + + $this->productMock->expects($this->any()) + ->method('getId') + ->willReturn($productId); + $this->productAttributeMock->expects($this->any()) + ->method('getIsRequired') + ->willReturn($productRequired); + + $this->productAttributeMock->expects($this->any()) + ->method('getDefaultValue') + ->willReturn($productRequired? 'required_value' : null); + + $this->productAttributeMock->expects($this->any()) + ->method('getAttributeCode') + ->willReturn('code'); + + $this->productAttributeMock->expects($this->any()) + ->method('getValue') + ->willReturn('value'); + + $attributeMock = $this->getMockBuilder(AttributeInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $attributeMock->expects($this->any()) + ->method('getValue') + ->willReturn($attrValue); + + $this->productMock->expects($this->any()) + ->method('getCustomAttribute') + ->willReturn($attributeMock); + + $this->arrayManagerMock->expects($this->any()) + ->method('set') + ->with( + $configPath, + [], + $expected + ) + ->willReturn($expected); + + $this->arrayManagerMock->expects($this->any()) + ->method('merge') + ->willReturn($expected); + + $this->arrayManagerMock->expects($this->any()) + ->method('get') + ->willReturn([]); + + $this->arrayManagerMock->expects($this->any()) + ->method('exists'); + + $this->assertEquals( + $expected, + $this->eav->setupAttributeMeta($this->productAttributeMock, $groupCode, $sortOrder) + ); + } + + /** + * @return array + */ + public function setupAttributeMetaDataProvider() + { + return [ + 'default_null_prod_not_new_and_required' => [ + 'productId' => 1, + 'productRequired' => true, + 'attrValue' => null, + 'expected' => [ + 'dataType' => null, + 'formElement' => null, + 'visible' => null, + 'required' => true, + 'notice' => null, + 'default' => 'required_value', + 'label' => null, + 'code' => 'code', + 'source' => 'product-details', + 'scopeLabel' => '', + 'globalScope' => false, + 'sortOrder' => 0 + ], + ], + 'default_null_prod_not_new_and_required_with_value' => [ + 'productId' => 1, + 'productRequired' => true, + 'attrValue' => 'val', + 'expected' => [ + 'dataType' => null, + 'formElement' => null, + 'visible' => null, + 'required' => true, + 'notice' => null, + 'default' => null, + 'label' => null, + 'code' => 'code', + 'source' => 'product-details', + 'scopeLabel' => '', + 'globalScope' => false, + 'sortOrder' => 0 + ], + ], + 'default_null_prod_not_new_and_not_required_no_value' => [ + 'productId' => 1, + 'productRequired' => false, + 'attrValue' => null, + 'expected' => [ + 'dataType' => null, + 'formElement' => null, + 'visible' => null, + 'required' => false, + 'notice' => null, + 'default' => null, + 'label' => null, + 'code' => 'code', + 'source' => 'product-details', + 'scopeLabel' => '', + 'globalScope' => false, + 'sortOrder' => 0 + ], + ], + 'default_null_prod_NEW_no_value' => [ + 'productId' => null, + 'productRequired' => true, + 'attrValue' => null, + 'expected' => [ + 'dataType' => null, + 'formElement' => null, + 'visible' => null, + 'required' => true, + 'notice' => null, + 'default' => 'required_value', + 'label' => null, + 'code' => 'code', + 'source' => 'product-details', + 'scopeLabel' => '', + 'globalScope' => false, + 'sortOrder' => 0 + ], + ], + ]; + } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index af7293ad920..e60d459dbcf 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -571,6 +571,7 @@ class Eav extends AbstractModifier * @return array * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) * @api */ public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupCode, $sortOrder) -- GitLab From 29db725aed0fd99e385d0201948aa65c051e2d5f Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Tue, 16 Aug 2016 10:59:21 +0300 Subject: [PATCH 473/838] MAGETWO-56954: Shopping cart page - Reordered items count is not getting updated at mini cart --- .../Sales/view/frontend/templates/order/history.phtml | 5 ++++- .../Sales/view/frontend/templates/order/info/buttons.phtml | 5 ++++- .../Magento/Sales/view/frontend/templates/order/recent.phtml | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/view/frontend/templates/order/history.phtml b/app/code/Magento/Sales/view/frontend/templates/order/history.phtml index 47ea803530f..c900b72af55 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/history.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/history.phtml @@ -42,7 +42,10 @@ <span><?php /* @escapeNotVerified */ echo __('View Order') ?></span> </a> <?php if ($this->helper('Magento\Sales\Helper\Reorder')->canReorder($_order->getEntityId())) : ?> - <a href="<?php /* @escapeNotVerified */ echo $block->getReorderUrl($_order) ?>" class="action order"> + <a href="#" data-post='<?php /* @escapeNotVerified */ echo + $this->helper(\Magento\Framework\Data\Helper\PostHelper::class) + ->getPostData($block->getReorderUrl($_order)) + ?>' class="action order"> <span><?php /* @escapeNotVerified */ echo __('Reorder') ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml b/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml index 2e1145662c3..9643bd22676 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml @@ -10,7 +10,10 @@ <div class="actions"> <?php $_order = $block->getOrder() ?> <?php if ($this->helper('Magento\Sales\Helper\Reorder')->canReorder($_order->getEntityId())) : ?> - <a class="action reorder" href="<?php /* @escapeNotVerified */ echo $block->getReorderUrl($_order) ?>"> + <a href="#" data-post='<?php /* @escapeNotVerified */ echo + $this->helper(\Magento\Framework\Data\Helper\PostHelper::class) + ->getPostData($block->getReorderUrl($_order)) + ?>' class="action order"> <span><?php /* @escapeNotVerified */ echo __('Reorder') ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml b/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml index b351fb6c86d..caf8a4abd2c 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/recent.phtml @@ -46,7 +46,10 @@ <span><?php /* @escapeNotVerified */ echo __('View Order') ?></span> </a> <?php if ($this->helper('Magento\Sales\Helper\Reorder')->canReorder($_order->getEntityId())) : ?> - <a href="<?php /* @escapeNotVerified */ echo $block->getReorderUrl($_order) ?>" class="action order"> + <a href="#" data-post='<?php /* @escapeNotVerified */ echo + $this->helper(\Magento\Framework\Data\Helper\PostHelper::class) + ->getPostData($block->getReorderUrl($_order)) + ?>' class="action order"> <span><?php /* @escapeNotVerified */ echo __('Reorder') ?></span> </a> <?php endif ?> -- GitLab From 4b7e5b92061750613fe61721947e8903e95ef8b3 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 18 Aug 2016 09:59:29 +0300 Subject: [PATCH 474/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Magento/Newsletter/Model/Plugin/CustomerPlugin.php | 9 +++++---- .../Test/Unit/Model/Plugin/CustomerPluginTest.php | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index a9e9a6abb97..5aeb3d284d7 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -34,16 +34,17 @@ class CustomerPlugin * * @param CustomerRepository $subject * @param CustomerInterface $result + * @param CustomerInterface $customer * @return CustomerInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterSave(CustomerRepository $subject, CustomerInterface $result) + public function afterSave(CustomerRepository $subject, CustomerInterface $result, CustomerInterface $customer) { $this->subscriberFactory->create()->updateSubscription($result->getId()); - if ($result->getId() && $result->getExtensionAttributes()) { - if ($result->getExtensionAttributes()->getIsSubscribed() === true) { + if ($result->getId() && $customer->getExtensionAttributes()) { + if ($customer->getExtensionAttributes()->getIsSubscribed() === true) { $this->subscriberFactory->create()->subscribeCustomerById($result->getId()); - } elseif ($result->getExtensionAttributes()->getIsSubscribed() === false) { + } elseif ($customer->getExtensionAttributes()->getIsSubscribed() === false) { $this->subscriberFactory->create()->unsubscribeCustomerById($result->getId()); } } diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php index 2975d8aaeb4..0b874de7b70 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php @@ -72,7 +72,7 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->method("getId") ->willReturn($customerId); - $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer)); + $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer, $customer)); } /** @@ -125,7 +125,7 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase ->method("getId") ->willReturn($customerId); - $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer)); + $this->assertEquals($customer, $this->plugin->afterSave($subject, $customer, $customer)); } public function testAfterDelete() -- GitLab From e3dc161b37a26391efcf14317676e6f2a1669b99 Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Thu, 18 Aug 2016 11:16:54 +0300 Subject: [PATCH 475/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php index 43f8e16a66c..b719babf209 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php @@ -29,6 +29,7 @@ use Psr\Log\LoggerInterface; /** * Class ShipOrderTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class ShipOrderTest extends \PHPUnit_Framework_TestCase { -- GitLab From eeca31a51d365776a499736a1d41540332804baa Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Thu, 18 Aug 2016 11:21:07 +0300 Subject: [PATCH 476/838] MAGETWO-56703: Around plugins refactoring: stabilize code --- .../Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php index 33be7fd8251..744ea82d2f1 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php @@ -66,5 +66,4 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(true)); $this->_plugin->beforeDispatch($this->subjectMock, $this->requestMock); } - } -- GitLab From 6a3763c77c1b986be48985838e00ff26bd8c291f Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 18 Aug 2016 11:22:27 +0300 Subject: [PATCH 477/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../ConfigurableProduct/Model/Product/Validator/Plugin.php | 2 +- .../Test/Unit/Model/Product/Validator/PluginTest.php | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php index c8f525cd462..05659796b2f 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php @@ -82,7 +82,7 @@ class Plugin $result, \Magento\Catalog\Model\Product $product, \Magento\Framework\App\RequestInterface $request, - \Magento\Framework\DataObject $response + DataObject $response ) { $variationProducts = (array)$request->getPost('variations-matrix'); if ($variationProducts) { diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php index d16788e10c4..466cc0266ad 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php @@ -111,7 +111,12 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->requestMock->expects(static::once())->method('has')->with('attributes')->willReturn(true); $this->productMock->expects(static::once())->method('setTypeId')->willReturnSelf(); - $this->plugin->beforeValidate($this->subjectMock, $this->productMock, $this->requestMock); + $this->plugin->beforeValidate( + $this->subjectMock, + $this->productMock, + $this->requestMock, + $this->responseMock + ); } public function testAroundValidateWithVariationsValid() -- GitLab From 2e5fe1fbe1721618b2b7653c3ca3141d0231317e Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Thu, 18 Aug 2016 11:30:51 +0300 Subject: [PATCH 478/838] MAGETWO-56703: Around plugins refactoring: stabilize code --- .../PageCache/Model/Controller/Result/BuiltinPlugin.php | 2 ++ .../Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php index 5900a37bad6..d2ef015fb69 100644 --- a/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php +++ b/app/code/Magento/PageCache/Model/Controller/Result/BuiltinPlugin.php @@ -16,6 +16,8 @@ use Magento\PageCache\Model\Cache\Type as CacheType; /** * Plugin for processing builtin cache + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class BuiltinPlugin { diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php index 9ecbb897b4b..1fd9bb5fe63 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php @@ -131,7 +131,8 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->plugin = (new ObjectManager($this))->getObject(\Magento\Store\App\Action\Plugin\Context::class, + $this->plugin = (new ObjectManager($this))->getObject( + \Magento\Store\App\Action\Plugin\Context::class, [ 'session' => $this->sessionMock, 'httpContext' => $this->httpContextMock, -- GitLab From 29bbe77c2d3356d05b4baa42f1a3bc29b0079e57 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 18 Aug 2016 13:44:47 +0300 Subject: [PATCH 479/838] MAGETWO-57127: Notification messages area. Incorrect loader height --- .../ui_component/notification_area.xml | 1 + .../view/adminhtml/web/js/grid/listing.js | 61 +++++++++++++++++++ .../adminhtml/web/template/grid/listing.html | 8 +-- .../web/css/source/_module.less | 22 ++++++- 4 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js diff --git a/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml b/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml index 5b79a721391..8a8cdb40b5e 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml +++ b/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml @@ -33,6 +33,7 @@ <columns name="columns"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_AdminNotification/js/grid/listing</item> <item name="template" xsi:type="string">Magento_AdminNotification/grid/listing</item> </item> </argument> diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js new file mode 100644 index 00000000000..60e2b296218 --- /dev/null +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js @@ -0,0 +1,61 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'Magento_Ui/js/grid/listing', + 'Magento_Ui/js/lib/spinner', + 'jquery' +], function (Listing, loader, $) { + 'use strict'; + + return Listing.extend({ + defaults: { + imports: { + totalRecords: '${ $.provider }:data.totalRecords' + }, + selectors: { + collapsible: '.message-system-collapsible', + messages: '.message-system' + } + }, + + /** @inheritdoc */ + initObservable: function () { + this._super() + .track({ + totalRecords: 0 + }); + + return this; + }, + + /** @inheritdoc */ + showLoader: function () { + this.fixLoaderHeight(); + this._super(); + }, + + /** + * Calculate loader height + * + * @param {Boolean} [closed] + */ + fixLoaderHeight: function (closed) { + var $messagesBlock = $(this.selectors.messages), + $collapsibleBlock = $(this.selectors.collapsible), + resultHeight = 0; + + if ($messagesBlock.length) { + resultHeight += $messagesBlock.outerHeight(); + } + + if ($collapsibleBlock.length && $collapsibleBlock.is(':visible') && !closed) { + resultHeight += $collapsibleBlock.outerHeight(); + } + + loader.get(this.name).height(resultHeight); + } + }); +}); diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html index ba4396a01b6..ee9efdfc4cb 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html @@ -4,13 +4,13 @@ * See COPYING.txt for license details. */ --> -<div id="system_messages" class="message-system"> - <div class="message-system-inner" data-bind="collapsible"> +<div id="system_messages" class="message-system" collapsible> + <div class="message-system-inner" outerClick="fixLoaderHeight.bind($data, true)"> <div class="message-system-short"> - <button data-bind="toggleCollapsible" class="message-system-action-dropdown"> + <button class="message-system-action-dropdown" toggleCollapsible> <span> <translate args="'System Messages'"/>: - <text args="rows.length"/> + <text args="totalRecords"/> </span> </button> <div class="message-system-short-wrapper" if="rows[0]" repeat="foreach: [rows[0]], item: '$row'" visible="!$collapsible.opened()"> diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 69aeb0ef930..1d8e98f0a13 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -9,8 +9,10 @@ @message-system__background-color: @color-lazy-sun; @message-system__border-color: @color-gray82; +@message-system__border-width: .1rem; @message-system__color: @color-gray20; @message-system-short-message__padding-vertical: 1.5rem; +@message-system-short-wrapper__height: 5rem; // Triangle marker @message-system-triangle__height: .5rem; @@ -25,7 +27,7 @@ &:extend(.abs-clearfix all); background: @message-system__background-color; border: solid @message-system__border-color; - border-width: 0 1px 1px; + border-width: 0 @message-system__border-width @message-system__border-width; position: relative; .message-error { @@ -67,6 +69,10 @@ } } +.message-system-short { + height: @message-system-short-wrapper__height; +} + .message-system-short-wrapper { overflow: hidden; padding: 0 1.5rem 0 @indent__l; @@ -74,7 +80,7 @@ .message-system-collapsible { background: @message-system__background-color; - border: 1px solid @message-system__border-color; + border: @message-system__border-width solid @message-system__border-color; border-top: 0; display: none; left: -1px; @@ -82,7 +88,7 @@ position: absolute; right: -1px; top: 100%; - z-index: @z-index-8; + z-index: @z-index-5 - 2; ._active & { display: block; @@ -121,3 +127,13 @@ } } } + +.notices-wrapper { + .admin__data-grid-loading-mask { + z-index: @z-index-5 - 1; + } + + .admin__data-grid-outer-wrap { + min-height: @message-system-short-wrapper__height + @message-system__border-width; + } +} -- GitLab From 9f413d68ed39ea2d555f05a11706a4bc856c3c48 Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Thu, 18 Aug 2016 14:18:04 +0300 Subject: [PATCH 480/838] MAGETWO-55953: Exception occurs when tracking shipment with invalid FedEx tracking number - Fixed type hinting --- app/code/Magento/Fedex/Model/Carrier.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php index 753388dc17b..3fe23389ea7 100644 --- a/app/code/Magento/Fedex/Model/Carrier.php +++ b/app/code/Magento/Fedex/Model/Carrier.php @@ -1089,9 +1089,12 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C * @param \stdClass $response * @return void */ - protected function _parseTrackingResponse($trackingValue, \stdClass $response) + protected function _parseTrackingResponse($trackingValue, $response) { - if (in_array($response->HighestSeverity, self::$trackingErrors)) { + if (!is_object($response) || empty($response->HighestSeverity)) { + $this->appendTrackingError($trackingValue, __('Invalid response from carrier')); + return; + } else if (in_array($response->HighestSeverity, self::$trackingErrors)) { $this->appendTrackingError($trackingValue, (string) $response->Notifications->Message); return; } else if (empty($response->CompletedTrackDetails) || empty($response->CompletedTrackDetails->TrackDetails)) { -- GitLab From 2c3f4b26108c53a5f54ddc0f84bdf117592eee20 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 18 Aug 2016 14:54:19 +0300 Subject: [PATCH 481/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Data/ShipmentPackageCreationInterface.php | 33 ++++++++++ .../Magento/Sales/Api/ShipOrderInterface.php | 2 +- .../Model/Order/Shipment/PackageCreation.php | 36 +++++++++++ .../Validation/QuantityValidator.php} | 7 +- .../Shipment/Validation/TrackValidator.php | 30 +++++++++ .../Model/Order/ShipmentDocumentFactory.php | 64 ++++++++++--------- app/code/Magento/Sales/Model/ShipOrder.php | 31 +++++---- app/code/Magento/Sales/etc/di.xml | 1 + 8 files changed, 156 insertions(+), 48 deletions(-) create mode 100644 app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php rename app/code/Magento/Sales/Model/Order/{ShipmentQuantityValidator.php => Shipment/Validation/QuantityValidator.php} (93%) create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php diff --git a/app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php new file mode 100644 index 00000000000..c83c54b3019 --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Data; + +/** + * Shipment package interface. + * + * A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This + * document lists the products and their quantities in the delivery package. + * @api + */ +interface ShipmentPackageCreationInterface extends \Magento\Framework\Api\ExtensibleDataInterface +{ + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/Sales/Api/ShipOrderInterface.php b/app/code/Magento/Sales/Api/ShipOrderInterface.php index 58f17ff7cc8..d28fedf4e50 100644 --- a/app/code/Magento/Sales/Api/ShipOrderInterface.php +++ b/app/code/Magento/Sales/Api/ShipOrderInterface.php @@ -21,7 +21,7 @@ interface ShipOrderInterface * @param bool $appendComment * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments * @return int Id of created Shipment. */ diff --git a/app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php new file mode 100644 index 00000000000..50ad944b825 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Class PackageCreation + * @api + */ +class PackageCreation implements \Magento\Sales\Api\Data\ShipmentPackageCreationInterface +{ + /** + * @var \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface + */ + private $extensionAttributes; + + /** + * {@inheritdoc} + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * {@inheritdoc} + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + return $this; + } +} diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php similarity index 93% rename from app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php rename to app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php index bce62402ba3..e0db63cd7c4 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php @@ -3,20 +3,19 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Sales\Model\Order; +namespace Magento\Sales\Model\Order\Shipment\Validation; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentInterface; -use Magento\Sales\Api\Data\ShipmentItemInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Exception\DocumentValidationException; use Magento\Sales\Model\ValidatorInterface; /** - * Class ShipmentQuantityValidator + * Class QuantityValidator */ -class ShipmentQuantityValidator implements ValidatorInterface +class QuantityValidator implements ValidatorInterface { /** * @var OrderRepositoryInterface diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php new file mode 100644 index 00000000000..01efae2f1e6 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment\Validation; + +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Model\ValidatorInterface; + +/** + * Class TrackRequiredField + */ +class TrackValidator implements ValidatorInterface +{ + /** + * @param object|ShipmentInterface $entity + * @return string[] + */ + public function validate($entity) + { + $messages = []; + foreach ($entity->getTracks() as $track) { + if (!$track->getTrackNumber()) { + $messages[] = __('Please enter a tracking number.'); + } + } + return $messages; + } +} diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index baf6acbd279..0ca549b9e50 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -6,6 +6,15 @@ namespace Magento\Sales\Model\Order; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentItemCreationInterface; +use Magento\Sales\Api\Data\ShipmentPackageCreationInterface; +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; +use Magento\Framework\EntityManager\HydratorPool; +use Magento\Sales\Model\Order\Shipment\TrackFactory; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; +use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; /** * Class InvoiceDocumentFactory * @@ -14,31 +23,31 @@ namespace Magento\Sales\Model\Order; class ShipmentDocumentFactory { /** - * @var \Magento\Framework\EntityManager\HydratorPool + * @var ShipmentFactory */ private $shipmentFactory; /** - * @var \Magento\Sales\Model\Order\Shipment\TrackFactory + * @var TrackFactory */ private $trackFactory; /** - * @var \Magento\Framework\EntityManager\HydratorPool + * @var HydratorPool */ private $hydratorPool; /** * ShipmentDocumentFactory constructor. * - * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory - * @param \Magento\Framework\EntityManager\HydratorPool $hydratorPool - * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + * @param ShipmentFactory $shipmentFactory + * @param HydratorPool $hydratorPool + * @param TrackFactory $trackFactory */ public function __construct( - \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory, - \Magento\Framework\EntityManager\HydratorPool $hydratorPool, - \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + ShipmentFactory $shipmentFactory, + HydratorPool $hydratorPool, + TrackFactory $trackFactory ) { $this->shipmentFactory = $shipmentFactory; $this->trackFactory = $trackFactory; @@ -46,24 +55,25 @@ class ShipmentDocumentFactory } /** - * @param \Magento\Sales\Api\Data\OrderInterface $order - * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items - * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment - * @param bool $appendComment - * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages - * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments - * @return Shipment * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * + * @param OrderInterface $order + * @param ShipmentItemCreationInterface[] $items + * @param ShipmentTrackCreationInterface[] $tracks + * @param ShipmentCommentCreationInterface|null $comment + * @param bool $appendComment + * @param ShipmentPackageCreationInterface[] $packages + * @param ShipmentCreationArgumentsInterface|null $arguments + * @return ShipmentInterface */ public function create( - \Magento\Sales\Api\Data\OrderInterface $order, + OrderInterface $order, array $items = [], array $tracks = [], - \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + ShipmentCommentCreationInterface $comment = null, $appendComment = false, array $packages = [], - \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null + ShipmentCreationArgumentsInterface $arguments = null ) { $shipmentItems = $this->itemsToArray($items); @@ -87,19 +97,13 @@ class ShipmentDocumentFactory /** * Adds tracks to the shipment. * - * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment - * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @throws \Magento\Framework\Exception\LocalizedException - * @return \Magento\Sales\Api\Data\ShipmentInterface + * @param ShipmentInterface $shipment + * @param ShipmentTrackCreationInterface[] $tracks + * @return ShipmentInterface */ private function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks) { foreach ($tracks as $track) { - if (!$track->getTrackNumber()) { - throw new \Magento\Framework\Exception\LocalizedException( - __('Please enter a tracking number.') - ); - } $hydrator = $this->hydratorPool->getHydrator( \Magento\Sales\Api\Data\ShipmentTrackCreationInterface::class ); @@ -111,7 +115,7 @@ class ShipmentDocumentFactory /** * Convert Items To Array * - * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items + * @param ShipmentItemCreationInterface[] $items * @return array */ private function itemsToArray($items = []) diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php index b5498b1085b..e7fd7707a12 100644 --- a/app/code/Magento/Sales/Model/ShipOrder.php +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -15,7 +15,8 @@ use Magento\Sales\Model\Order\OrderValidatorInterface; use Magento\Sales\Model\Order\ShipmentDocumentFactory; use Magento\Sales\Model\Order\Shipment\NotifierInterface; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; -use Magento\Sales\Model\Order\ShipmentQuantityValidator; +use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator; +use Magento\Sales\Model\Order\Shipment\Validation\TrackValidator; use Magento\Sales\Model\Order\Validation\CanShip; use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface; use Psr\Log\LoggerInterface; @@ -128,7 +129,7 @@ class ShipOrder implements ShipOrderInterface * @param bool $appendComment * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments * @return int * @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface @@ -158,19 +159,23 @@ class ShipOrder implements ShipOrderInterface $packages, $arguments ); - $errorMessages = array_merge( - $this->orderValidator->validate( - $order, - [CanShip::class] - ), - $this->shipmentValidator->validate( - $shipment, - [ShipmentQuantityValidator::class] - ) + $orderValidationResult = $this->orderValidator->validate( + $order, + [ + CanShip::class + ] + ); + $invoiceValidationResult = $this->shipmentValidator->validate( + $shipment, + [ + QuantityValidator::class, + TrackValidator::class + ] ); - if (!empty($errorMessages)) { + $validationMessages = array_merge($orderValidationResult, $invoiceValidationResult); + if (!empty($validationMessages)) { throw new \Magento\Sales\Exception\DocumentValidationException( - __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + __("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages)) ); } $connection->beginTransaction(); diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 10e404631e9..802445bb70b 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -96,6 +96,7 @@ <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <preference for="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" type="Magento\Sales\Model\Order\Shipment\TrackCreation"/> <preference for="Magento\Sales\Api\Data\ShipmentPackageInterface" type="Magento\Sales\Model\Order\Shipment\Package"/> + <preference for="Magento\Sales\Api\Data\ShipmentPackageCreationInterface" type="Magento\Sales\Model\Order\Shipment\PackageCreation"/> <preference for="Magento\Sales\Model\Order\OrderValidatorInterface" type="Magento\Sales\Model\Order\OrderValidator"/> <preference for="Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface" type="Magento\Sales\Model\Order\Invoice\InvoiceValidator"/> <preference for="Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface" type="Magento\Sales\Model\Order\Shipment\ShipmentValidator"/> -- GitLab From 05b64184766004a13dae7c3d1d19fdd4545c50ba Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 18 Aug 2016 14:54:19 +0300 Subject: [PATCH 482/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Data/ShipmentPackageCreationInterface.php | 33 ++++++++++ .../Magento/Sales/Api/ShipOrderInterface.php | 2 +- .../Model/Order/Shipment/PackageCreation.php | 36 +++++++++++ .../Validation/QuantityValidator.php} | 7 +- .../Shipment/Validation/TrackValidator.php | 30 +++++++++ .../Model/Order/ShipmentDocumentFactory.php | 64 ++++++++++--------- app/code/Magento/Sales/Model/ShipOrder.php | 31 +++++---- app/code/Magento/Sales/etc/di.xml | 1 + 8 files changed, 156 insertions(+), 48 deletions(-) create mode 100644 app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php rename app/code/Magento/Sales/Model/Order/{ShipmentQuantityValidator.php => Shipment/Validation/QuantityValidator.php} (93%) create mode 100644 app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php diff --git a/app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php new file mode 100644 index 00000000000..c83c54b3019 --- /dev/null +++ b/app/code/Magento/Sales/Api/Data/ShipmentPackageCreationInterface.php @@ -0,0 +1,33 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Api\Data; + +/** + * Shipment package interface. + * + * A shipment is a delivery package that contains products. A shipment document accompanies the shipment. This + * document lists the products and their quantities in the delivery package. + * @api + */ +interface ShipmentPackageCreationInterface extends \Magento\Framework\Api\ExtensibleDataInterface +{ + /** + * Retrieve existing extension attributes object or create a new one. + * + * @return \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface|null + */ + public function getExtensionAttributes(); + + /** + * Set an extension attributes object. + * + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface $extensionAttributes + * @return $this + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface $extensionAttributes + ); +} diff --git a/app/code/Magento/Sales/Api/ShipOrderInterface.php b/app/code/Magento/Sales/Api/ShipOrderInterface.php index 58f17ff7cc8..d28fedf4e50 100644 --- a/app/code/Magento/Sales/Api/ShipOrderInterface.php +++ b/app/code/Magento/Sales/Api/ShipOrderInterface.php @@ -21,7 +21,7 @@ interface ShipOrderInterface * @param bool $appendComment * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments * @return int Id of created Shipment. */ diff --git a/app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php new file mode 100644 index 00000000000..50ad944b825 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/PackageCreation.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment; + +/** + * Class PackageCreation + * @api + */ +class PackageCreation implements \Magento\Sales\Api\Data\ShipmentPackageCreationInterface +{ + /** + * @var \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface + */ + private $extensionAttributes; + + /** + * {@inheritdoc} + */ + public function getExtensionAttributes() + { + return $this->extensionAttributes; + } + + /** + * {@inheritdoc} + */ + public function setExtensionAttributes( + \Magento\Sales\Api\Data\ShipmentPackageCreationExtensionInterface $extensionAttributes + ) { + $this->extensionAttributes = $extensionAttributes; + return $this; + } +} diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php similarity index 93% rename from app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php rename to app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php index bce62402ba3..e0db63cd7c4 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php @@ -3,20 +3,19 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Sales\Model\Order; +namespace Magento\Sales\Model\Order\Shipment\Validation; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentInterface; -use Magento\Sales\Api\Data\ShipmentItemInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Exception\DocumentValidationException; use Magento\Sales\Model\ValidatorInterface; /** - * Class ShipmentQuantityValidator + * Class QuantityValidator */ -class ShipmentQuantityValidator implements ValidatorInterface +class QuantityValidator implements ValidatorInterface { /** * @var OrderRepositoryInterface diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php new file mode 100644 index 00000000000..01efae2f1e6 --- /dev/null +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Model\Order\Shipment\Validation; + +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Model\ValidatorInterface; + +/** + * Class TrackRequiredField + */ +class TrackValidator implements ValidatorInterface +{ + /** + * @param object|ShipmentInterface $entity + * @return string[] + */ + public function validate($entity) + { + $messages = []; + foreach ($entity->getTracks() as $track) { + if (!$track->getTrackNumber()) { + $messages[] = __('Please enter a tracking number.'); + } + } + return $messages; + } +} diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index baf6acbd279..0ca549b9e50 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -6,6 +6,15 @@ namespace Magento\Sales\Model\Order; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentItemCreationInterface; +use Magento\Sales\Api\Data\ShipmentPackageCreationInterface; +use Magento\Sales\Api\Data\ShipmentTrackCreationInterface; +use Magento\Framework\EntityManager\HydratorPool; +use Magento\Sales\Model\Order\Shipment\TrackFactory; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; +use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; /** * Class InvoiceDocumentFactory * @@ -14,31 +23,31 @@ namespace Magento\Sales\Model\Order; class ShipmentDocumentFactory { /** - * @var \Magento\Framework\EntityManager\HydratorPool + * @var ShipmentFactory */ private $shipmentFactory; /** - * @var \Magento\Sales\Model\Order\Shipment\TrackFactory + * @var TrackFactory */ private $trackFactory; /** - * @var \Magento\Framework\EntityManager\HydratorPool + * @var HydratorPool */ private $hydratorPool; /** * ShipmentDocumentFactory constructor. * - * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory - * @param \Magento\Framework\EntityManager\HydratorPool $hydratorPool - * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + * @param ShipmentFactory $shipmentFactory + * @param HydratorPool $hydratorPool + * @param TrackFactory $trackFactory */ public function __construct( - \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory, - \Magento\Framework\EntityManager\HydratorPool $hydratorPool, - \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + ShipmentFactory $shipmentFactory, + HydratorPool $hydratorPool, + TrackFactory $trackFactory ) { $this->shipmentFactory = $shipmentFactory; $this->trackFactory = $trackFactory; @@ -46,24 +55,25 @@ class ShipmentDocumentFactory } /** - * @param \Magento\Sales\Api\Data\OrderInterface $order - * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items - * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment - * @param bool $appendComment - * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages - * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments - * @return Shipment * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * + * @param OrderInterface $order + * @param ShipmentItemCreationInterface[] $items + * @param ShipmentTrackCreationInterface[] $tracks + * @param ShipmentCommentCreationInterface|null $comment + * @param bool $appendComment + * @param ShipmentPackageCreationInterface[] $packages + * @param ShipmentCreationArgumentsInterface|null $arguments + * @return ShipmentInterface */ public function create( - \Magento\Sales\Api\Data\OrderInterface $order, + OrderInterface $order, array $items = [], array $tracks = [], - \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null, + ShipmentCommentCreationInterface $comment = null, $appendComment = false, array $packages = [], - \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null + ShipmentCreationArgumentsInterface $arguments = null ) { $shipmentItems = $this->itemsToArray($items); @@ -87,19 +97,13 @@ class ShipmentDocumentFactory /** * Adds tracks to the shipment. * - * @param \Magento\Sales\Api\Data\ShipmentInterface $shipment - * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @throws \Magento\Framework\Exception\LocalizedException - * @return \Magento\Sales\Api\Data\ShipmentInterface + * @param ShipmentInterface $shipment + * @param ShipmentTrackCreationInterface[] $tracks + * @return ShipmentInterface */ private function prepareTracks(\Magento\Sales\Api\Data\ShipmentInterface $shipment, array $tracks) { foreach ($tracks as $track) { - if (!$track->getTrackNumber()) { - throw new \Magento\Framework\Exception\LocalizedException( - __('Please enter a tracking number.') - ); - } $hydrator = $this->hydratorPool->getHydrator( \Magento\Sales\Api\Data\ShipmentTrackCreationInterface::class ); @@ -111,7 +115,7 @@ class ShipmentDocumentFactory /** * Convert Items To Array * - * @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items + * @param ShipmentItemCreationInterface[] $items * @return array */ private function itemsToArray($items = []) diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php index b5498b1085b..e7fd7707a12 100644 --- a/app/code/Magento/Sales/Model/ShipOrder.php +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -15,7 +15,8 @@ use Magento\Sales\Model\Order\OrderValidatorInterface; use Magento\Sales\Model\Order\ShipmentDocumentFactory; use Magento\Sales\Model\Order\Shipment\NotifierInterface; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; -use Magento\Sales\Model\Order\ShipmentQuantityValidator; +use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator; +use Magento\Sales\Model\Order\Shipment\Validation\TrackValidator; use Magento\Sales\Model\Order\Validation\CanShip; use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface; use Psr\Log\LoggerInterface; @@ -128,7 +129,7 @@ class ShipOrder implements ShipOrderInterface * @param bool $appendComment * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment * @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks - * @param \Magento\Sales\Api\Data\ShipmentPackageInterface[] $packages + * @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments * @return int * @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface @@ -158,19 +159,23 @@ class ShipOrder implements ShipOrderInterface $packages, $arguments ); - $errorMessages = array_merge( - $this->orderValidator->validate( - $order, - [CanShip::class] - ), - $this->shipmentValidator->validate( - $shipment, - [ShipmentQuantityValidator::class] - ) + $orderValidationResult = $this->orderValidator->validate( + $order, + [ + CanShip::class + ] + ); + $invoiceValidationResult = $this->shipmentValidator->validate( + $shipment, + [ + QuantityValidator::class, + TrackValidator::class + ] ); - if (!empty($errorMessages)) { + $validationMessages = array_merge($orderValidationResult, $invoiceValidationResult); + if (!empty($validationMessages)) { throw new \Magento\Sales\Exception\DocumentValidationException( - __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) + __("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages)) ); } $connection->beginTransaction(); diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 10e404631e9..802445bb70b 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -96,6 +96,7 @@ <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <preference for="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" type="Magento\Sales\Model\Order\Shipment\TrackCreation"/> <preference for="Magento\Sales\Api\Data\ShipmentPackageInterface" type="Magento\Sales\Model\Order\Shipment\Package"/> + <preference for="Magento\Sales\Api\Data\ShipmentPackageCreationInterface" type="Magento\Sales\Model\Order\Shipment\PackageCreation"/> <preference for="Magento\Sales\Model\Order\OrderValidatorInterface" type="Magento\Sales\Model\Order\OrderValidator"/> <preference for="Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface" type="Magento\Sales\Model\Order\Invoice\InvoiceValidator"/> <preference for="Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface" type="Magento\Sales\Model\Order\Shipment\ShipmentValidator"/> -- GitLab From 35c38bf74644d08fc6148cb82da7b68fa9322acc Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Thu, 18 Aug 2016 15:25:42 +0300 Subject: [PATCH 483/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Shipping/Controller/Adminhtml/Order/ShipmentLoader.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index c1ad9653937..c4efe6f6507 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -1,15 +1,11 @@ <?php /** - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Shipping\Controller\Adminhtml\Order; -use Magento\Framework\App\ObjectManager; use Magento\Framework\DataObject; -use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; -use Magento\Sales\Model\Order\ShipmentQuantityValidator; /** * Class ShipmentLoader -- GitLab From e08c1a102b1420794c8a2b489e5400a70e84810b Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Thu, 18 Aug 2016 15:38:40 +0300 Subject: [PATCH 484/838] MAGETWO-54054: Compiler performance optimization - MAGETWO-57139: Improve search of paths which should be excluded from compilation - refactoring (extracting logic of excluded paths list building to private methods) --- .../Console/Command/DiCompileCommand.php | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index 65c0b090d63..820adde7d74 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -140,17 +140,9 @@ class DiCompileCommand extends Command 'library' => $libraryPaths, 'generated_helpers' => $generationPath ]; - $excludedModulePaths = []; - foreach ($modulePaths as $appCodePath) { - $excludedModulePaths[] = '#^' . $appCodePath . '/Test#'; - } - $excludedLibraryPaths = []; - foreach ($libraryPaths as $libraryPath) { - $excludedLibraryPaths[] = '#^' . $libraryPath . '/([\\w]+/)?Test#'; - } $this->excludedPathsList = [ - 'application' => $excludedModulePaths, - 'framework' => $excludedLibraryPaths + 'application' => $this->getExcludedModulePaths($modulePaths), + 'framework' => $this->getExcludedLibraryPaths($libraryPaths), ]; $this->configureObjectManager($output); @@ -205,6 +197,36 @@ class DiCompileCommand extends Command } } + /** + * Build list of module path regexps which should be excluded from compilation + * + * @param string[] $modulePaths + * @return string[] + */ + private function getExcludedModulePaths($modulePaths) + { + $excludedModulePaths = []; + foreach ($modulePaths as $appCodePath) { + $excludedModulePaths[] = '#^' . $appCodePath . '/Test#'; + } + return $excludedModulePaths; + } + + /** + * Build list of library path regexps which should be excluded from compilation + * + * @param string[] $libraryPaths + * @return string[] + */ + private function getExcludedLibraryPaths($libraryPaths) + { + $excludedLibraryPaths = []; + foreach ($libraryPaths as $libraryPath) { + $excludedLibraryPaths[] = '#^' . $libraryPath . '/([\\w]+/)?Test#'; + } + return $excludedLibraryPaths; + } + /** * Delete directories by their code from "var" directory * -- GitLab From 982e767768203e9b5b211dc71cfd99636e10eba6 Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Thu, 18 Aug 2016 15:41:40 +0300 Subject: [PATCH 485/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php | 1 - .../Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php index b01a0af5e50..8d800e12a6f 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/InvoiceQuantityValidatorTest.php @@ -45,7 +45,6 @@ class InvoiceQuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->orderMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderInterface::class) ->disableOriginalConstructor() - ->setMethods(['getStatus']) ->getMockForAbstractClass(); $this->invoiceMock = $this->getMockBuilder(\Magento\Sales\Api\Data\InvoiceInterface::class) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php index 93f6b7408d6..cd8481f75a0 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -63,12 +63,12 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase private $trackFactoryMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject|TrackFactory + * @var \PHPUnit_Framework_MockObject_MockObject|HydratorInterface */ private $hydratorMock; /** - * @var \PHPUnit_Framework_MockObject_MockObject|HydratorInterface + * @var \PHPUnit_Framework_MockObject_MockObject|Track */ private $trackMock; @@ -110,7 +110,6 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase $this->hydratorMock = $this->getMockBuilder(HydratorInterface::class) ->disableOriginalConstructor() - ->setMethods(['extract']) ->getMockForAbstractClass(); $this->invoiceDocumentFactory = new ShipmentDocumentFactory( -- GitLab From 028496bdaa18d33512ac002540f2d7f24dd80f91 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 18 Aug 2016 15:44:54 +0300 Subject: [PATCH 486/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Validation/QuantityValidatorTest.php | 61 +++++++++++++++++++ .../Validation/TrackValidatorTest.php | 61 +++++++++++++++++++ .../Order/ShipmentDocumentFactoryTest.php | 4 -- 3 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php create mode 100644 app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php new file mode 100644 index 00000000000..3d59b1d2936 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Order\Shipment\Validation; + +use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentItemInterface; + +/** + * Class QuantityValidatorTest + */ +class QuantityValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var QuantityValidator + */ + private $validator; + + /** + * @var ShipmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentMock; + + /** + * @var ShipmentItemInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentItemMock; + + protected function setUp() + { + $objectManagerHelper = new ObjectManager($this); + $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class) + ->getMock(); + $this->shipmentItemMock = $this->getMockBuilder(ShipmentItemInterface::class) + ->getMock(); + $this->validator = $objectManagerHelper->getObject(QuantityValidator::class); + } + + public function testValidateTrackWithoutOrderId() + { + $this->shipmentMock->expects($this->once()) + ->method('getOrderId') + ->willReturn(null); + $this->assertEquals([__('Order Id is required for shipment document')], $this->validator->validate($this->shipmentMock)); + } + + public function testValidateTrackWithoutItems() + { + $this->shipmentMock->expects($this->once()) + ->method('getOrderId') + ->willReturn(1); + $this->shipmentMock->expects($this->once()) + ->method('getItems') + ->willReturn(null); + $this->assertEquals([__('You can\'t create a shipment without products.')], $this->validator->validate($this->shipmentMock)); + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php new file mode 100644 index 00000000000..69e88bb4530 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Model\Order\Shipment\Validation; + +use Magento\Sales\Model\Order\Shipment\Validation\TrackValidator; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Sales\Api\Data\ShipmentInterface; +use Magento\Sales\Api\Data\ShipmentTrackInterface; + +/** + * Class QuantityValidatorTest + */ +class TrackValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var TrackValidator + */ + private $validator; + + /** + * @var ShipmentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentMock; + + /** + * @var ShipmentTrackInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $shipmentTrackMock; + + protected function setUp() + { + $objectManagerHelper = new ObjectManager($this); + $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class) + ->getMock(); + $this->shipmentTrackMock = $this->getMockBuilder(ShipmentTrackInterface::class) + ->getMock(); + $this->shipmentMock->expects($this->once()) + ->method('getTracks') + ->willReturn([$this->shipmentTrackMock]); + $this->validator = $objectManagerHelper->getObject(TrackValidator::class); + } + + public function testValidateTrackWithNumber() + { + $this->shipmentTrackMock->expects($this->once()) + ->method('getTrackNumber') + ->willReturn('12345'); + $this->assertEquals([], $this->validator->validate($this->shipmentMock)); + } + + public function testValidateTrackWithoutNumber() + { + $this->shipmentTrackMock->expects($this->once()) + ->method('getTrackNumber') + ->willReturn(null); + $this->assertEquals([__('Please enter a tracking number.')], $this->validator->validate($this->shipmentMock)); + } +} \ No newline at end of file diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php index 93f6b7408d6..75bc46e5aa3 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -145,10 +145,6 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase ) ->willReturn($this->shipmentMock); - $this->trackMock->expects($this->once()) - ->method('getTrackNumber') - ->willReturn($trackNum); - $this->shipmentMock->expects($this->once()) ->method('addTrack') ->willReturnSelf(); -- GitLab From 580d24cc7ba966c5c2c8a4105b4e2d59df6b6d91 Mon Sep 17 00:00:00 2001 From: Dmytro Voskoboinikov <dvoskoboinikov@magento.com> Date: Thu, 18 Aug 2016 15:50:49 +0300 Subject: [PATCH 487/838] MAGETWO-54677: Order status change after Shipment creation through API --- app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php index f36889353af..6e8ce097f41 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/TrackCreation.php @@ -32,6 +32,8 @@ class TrackCreation implements ShipmentTrackCreationInterface */ private $extensionAttributes; + //@codeCoverageIgnoreStart + /** * {@inheritdoc} */ @@ -100,4 +102,6 @@ class TrackCreation implements ShipmentTrackCreationInterface $this->extensionAttributes = $extensionAttributes; return $this; } + + //@codeCoverageIgnoreEnd } -- GitLab From 0f03bc9b3fd0a6b99b3671a142f15beb790e0346 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Thu, 18 Aug 2016 15:51:27 +0300 Subject: [PATCH 488/838] MAGETWO-56778: Value for multiple select attribute does not save --- app/code/Magento/Catalog/Model/ResourceModel/Product.php | 2 +- app/code/Magento/Eav/Model/Entity/AbstractEntity.php | 5 +++-- .../Framework/EntityManager/Observer/AfterEntitySave.php | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product.php b/app/code/Magento/Catalog/Model/ResourceModel/Product.php index a3be4a2f98a..96688766582 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product.php @@ -567,7 +567,7 @@ class Product extends AbstractResource */ public function load($object, $entityId, $attributes = []) { - $this->loadAttributesMetadata($attributes); + $this->loadAttributesMetadata($attributes, $object); $this->getEntityManager()->load($object, $entityId); return $this; } diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index c3e5a4b0c4d..506cf0c9680 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -975,12 +975,13 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac * Loads attributes metadata. * * @param array|null $attributes + * @param null|\Magento\Framework\DataObject $object * @return $this */ - protected function loadAttributesMetadata($attributes) + protected function loadAttributesMetadata($attributes, $object = null) { if (empty($attributes)) { - $this->loadAllAttributes(); + $this->loadAllAttributes($object); } else { if (!is_array($attributes)) { $attributes = [$attributes]; diff --git a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php index 9ca4a894739..dda098df179 100644 --- a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php +++ b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php @@ -28,7 +28,7 @@ class AfterEntitySave implements ObserverInterface $entity = $observer->getEvent()->getEntity(); if ($entity instanceof AbstractModel) { if (method_exists($entity->getResource(), 'loadAllAttributes')) { - $entity->getResource()->loadAllAttributes(); + $entity->getResource()->loadAllAttributes($entity); } $entity->getResource()->afterSave($entity); $entity->afterSave(); -- GitLab From 5b4f22aeb08b1740e4ff7546373fca64db676345 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 18 Aug 2016 15:52:58 +0300 Subject: [PATCH 489/838] MAGETWO-57127: Notification messages area. Incorrect loader height --- .../AdminNotification/view/adminhtml/web/js/grid/listing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js index 60e2b296218..716d3334886 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js @@ -38,7 +38,7 @@ define([ }, /** - * Calculate loader height + * Calculates loader height * * @param {Boolean} [closed] */ -- GitLab From 226a61f80e85d41d11db3f68ad83518e5a02065c Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 15:53:12 +0300 Subject: [PATCH 490/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Model/Order/ShipmentQuantityValidator.php | 33 ++++++++++++------- .../Model/Order/Validation/CanInvoice.php | 21 ++++++++---- .../Sales/Model/Order/Validation/CanShip.php | 17 +++++++--- .../Model/Order/Validation/CanInvoiceTest.php | 6 +++- .../Model/Order/Validation/CanShipTest.php | 6 +++- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php index bce62402ba3..fa7a60e8a6b 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentQuantityValidator.php @@ -7,6 +7,7 @@ namespace Magento\Sales\Model\Order; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\Data\ShipmentItemInterface; use Magento\Sales\Api\OrderRepositoryInterface; @@ -45,22 +46,31 @@ class ShipmentQuantityValidator implements ValidatorInterface return [__('Order Id is required for shipment document')]; } - if ($entity->getItems() === null) { + if (empty($entity->getItems())) { return [__('You can\'t create a shipment without products.')]; } $messages = []; $order = $this->orderRepository->get($entity->getOrderId()); + $orderItemsById = $this->getOrderItems($order); + $totalQuantity = 0; foreach ($entity->getItems() as $item) { - $orderItem = $this->getOrderItemById($order, $item->getOrderItemId()); - if ($orderItem === null) { - $messages[] = __('We can not found item "%1" in order.', $item->getOrderItemId()); + if (!isset($orderItemsById[$item->getOrderItemId()])) { + $messages[] = __( + 'The shipment contains product SKU "%1" that is not part of the original order.', + $item->getSku() + ); continue; } + $orderItem = $orderItemsById[$item->getOrderItemId()]; if (!$this->isQtyAvailable($orderItem, $item->getQty())) { - $messages[] =__('We found an invalid quantity to ship for item "%1".', $item->getName()); + $messages[] =__( + 'The quantity to ship must not be greater than the unshipped quantity' + . ' for product SKU "%1".', + $orderItem->getSku() + ); } else { $totalQuantity += $item->getQty(); } @@ -68,23 +78,22 @@ class ShipmentQuantityValidator implements ValidatorInterface if ($totalQuantity <= 0) { $messages[] = __('You can\'t create a shipment without products.'); } + return $messages; } /** * @param OrderInterface $order - * @param int $id - * @return \Magento\Sales\Api\Data\OrderItemInterface|null + * @return OrderItemInterface[] */ - private function getOrderItemById(OrderInterface $order, $id) + private function getOrderItems(OrderInterface $order) { + $orderItemsById = []; foreach ($order->getItems() as $item) { - if ($item->getItemId() === $id) { - return $item; - } + $orderItemsById[$item->getItemId()] = $item; } - return null; + return $orderItemsById; } /** diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index 106882418ab..c0f2771561e 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -21,18 +21,17 @@ class CanInvoice implements ValidatorInterface public function validate($entity) { $messages = []; - if (!$this->canInvoice($entity)) { + + if (!$this->isStateReadyForInvoice($entity)) { + $messages[] = __('An invoice cannot be created when an order has a status of %1', $entity->getStatus()); + } elseif (!$this->canInvoice($entity)) { $messages[] = __('The order does not allow an invoice to be created.'); } return $messages; } - /** - * @param OrderInterface $order - * @return bool - */ - private function canInvoice(OrderInterface $order) + private function isStateReadyForInvoice(OrderInterface $order) { if ($order->getState() === Order::STATE_PAYMENT_REVIEW || $order->getState() === Order::STATE_HOLDED || @@ -42,6 +41,16 @@ class CanInvoice implements ValidatorInterface ) { return false; }; + + return true; + } + + /** + * @param OrderInterface $order + * @return bool + */ + private function canInvoice(OrderInterface $order) + { /** @var \Magento\Sales\Model\Order\Item $item */ foreach ($order->getItems() as $item) { if ($item->getQtyToInvoice() > 0 && !$item->getLockedDoInvoice()) { diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php index cebdc4b0afe..a2e4da6eee1 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php @@ -5,9 +5,7 @@ */ namespace Magento\Sales\Model\Order\Validation; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; -use Magento\Sales\Exception\DocumentValidationException; use Magento\Sales\Model\Order; use Magento\Sales\Model\ValidatorInterface; @@ -23,7 +21,9 @@ class CanShip implements ValidatorInterface public function validate($entity) { $messages = []; - if (!$this->canShip($entity)) { + if (!$this->isStateReadyForShipment($entity)) { + $messages[] = __('A shipment cannot be created when an order has a status of %1', $entity->getStatus()); + } elseif (!$this->canShip($entity)) { $messages[] = __('The order does not allow a shipment to be created.'); } @@ -34,7 +34,7 @@ class CanShip implements ValidatorInterface * @param OrderInterface $order * @return bool */ - private function canShip(OrderInterface $order) + private function isStateReadyForShipment(OrderInterface $order) { if ($order->getState() === Order::STATE_PAYMENT_REVIEW || $order->getState() === Order::STATE_HOLDED || @@ -44,6 +44,15 @@ class CanShip implements ValidatorInterface return false; } + return true; + } + + /** + * @param OrderInterface $order + * @return bool + */ + private function canShip(OrderInterface $order) + { /** @var \Magento\Sales\Model\Order\Item $item */ foreach ($order->getItems() as $item) { if ($item->getQtyToShip() > 0 && !$item->getIsVirtual() && !$item->getLockedDoShip()) { diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php index f3d93d73474..dd76bc1e525 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanInvoiceTest.php @@ -62,7 +62,11 @@ class CanInvoiceTest extends \PHPUnit_Framework_TestCase ->willReturn($state); $this->orderMock->expects($this->never()) ->method('getItems'); - $this->assertNotEmpty( + $this->orderMock->expects($this->once()) + ->method('getStatus') + ->willReturn('status'); + $this->assertEquals( + [__('An invoice cannot be created when an order has a status of %1', 'status')], $this->model->validate($this->orderMock) ); } diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php index 44345372600..11d99fbb9cc 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Validation/CanShipTest.php @@ -60,9 +60,13 @@ class CanShipTest extends \PHPUnit_Framework_TestCase $this->orderMock->expects($this->any()) ->method('getState') ->willReturn($state); + $this->orderMock->expects($this->once()) + ->method('getStatus') + ->willReturn('status'); $this->orderMock->expects($this->never()) ->method('getItems'); - $this->assertNotEmpty( + $this->assertEquals( + [__('A shipment cannot be created when an order has a status of %1', 'status')], $this->model->validate($this->orderMock) ); } -- GitLab From d21cc67b777cc722c2dfb76ee88af17f7218c2de Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 15:56:10 +0300 Subject: [PATCH 491/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/Shipment/Validation/QuantityValidator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php index 192ea5b091f..f124fe9c6c0 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php @@ -11,6 +11,7 @@ use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Exception\DocumentValidationException; +use Magento\Sales\Model\Order\Item; use Magento\Sales\Model\ValidatorInterface; /** -- GitLab From 168b61c27febb411726b05dbb6b514a9aab2c996 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:10:34 +0300 Subject: [PATCH 492/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php b/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php index 58ad64a0e58..fa53f72ebca 100644 --- a/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php +++ b/app/code/Magento/Sales/Model/Order/Invoice/CommentCreation.php @@ -93,5 +93,6 @@ class CommentCreation implements InvoiceCommentCreationInterface \Magento\Sales\Api\Data\InvoiceCommentCreationExtensionInterface $extensionAttributes ) { $this->extensionAttributes = $extensionAttributes; + return $this; } } -- GitLab From 721f3b5a6cdd45b751940cca8b2ff25056b5a0aa Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:15:43 +0300 Subject: [PATCH 493/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Sales/Model/Order/Shipment/Validation/QuantityValidator.php | 2 +- .../Sales/Model/Order/Shipment/Validation/TrackValidator.php | 2 +- app/code/Magento/Sales/Model/Order/Validation/CanShip.php | 2 +- app/code/Magento/Sales/Model/ValidatorInterface.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php index f124fe9c6c0..20e3712d889 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/QuantityValidator.php @@ -36,7 +36,7 @@ class QuantityValidator implements ValidatorInterface /** * @param ShipmentInterface $entity - * @return string[] + * @return array * @throws DocumentValidationException * @throws NoSuchEntityException */ diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php index 01efae2f1e6..8ba20542da1 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php @@ -15,7 +15,7 @@ class TrackValidator implements ValidatorInterface { /** * @param object|ShipmentInterface $entity - * @return string[] + * @return array */ public function validate($entity) { diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php index a2e4da6eee1..46638a62483 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanShip.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanShip.php @@ -16,7 +16,7 @@ class CanShip implements ValidatorInterface { /** * @param OrderInterface $entity - * @return string[] + * @return array */ public function validate($entity) { diff --git a/app/code/Magento/Sales/Model/ValidatorInterface.php b/app/code/Magento/Sales/Model/ValidatorInterface.php index 6c50af2c685..1882782e314 100644 --- a/app/code/Magento/Sales/Model/ValidatorInterface.php +++ b/app/code/Magento/Sales/Model/ValidatorInterface.php @@ -15,7 +15,7 @@ interface ValidatorInterface { /** * @param object $entity - * @return string[] + * @return array * @throws DocumentValidationException * @throws NoSuchEntityException */ -- GitLab From 32fd5c5a351a3ebd49e4834311fc4d955ddb1191 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:24:26 +0300 Subject: [PATCH 494/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- app/code/Magento/Sales/Model/ShipOrder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php index e7fd7707a12..d051144cf73 100644 --- a/app/code/Magento/Sales/Model/ShipOrder.php +++ b/app/code/Magento/Sales/Model/ShipOrder.php @@ -165,14 +165,14 @@ class ShipOrder implements ShipOrderInterface CanShip::class ] ); - $invoiceValidationResult = $this->shipmentValidator->validate( + $shipmentValidationResult = $this->shipmentValidator->validate( $shipment, [ QuantityValidator::class, TrackValidator::class ] ); - $validationMessages = array_merge($orderValidationResult, $invoiceValidationResult); + $validationMessages = array_merge($orderValidationResult, $shipmentValidationResult); if (!empty($validationMessages)) { throw new \Magento\Sales\Exception\DocumentValidationException( __("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages)) -- GitLab From 81fd780aead006f62dcfa16a554853c785caecee Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:25:27 +0300 Subject: [PATCH 495/838] MAGETWO-54677: Order status change after Shipment creation through API - static fixes --- .../Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php index 69e88bb4530..8d050976145 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php @@ -11,7 +11,7 @@ use Magento\Sales\Api\Data\ShipmentInterface; use Magento\Sales\Api\Data\ShipmentTrackInterface; /** - * Class QuantityValidatorTest + * Class TrackValidatorTest */ class TrackValidatorTest extends \PHPUnit_Framework_TestCase { -- GitLab From d4f0d2a5dc830e8c8657c3c534101ddfcf007d6d Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:26:38 +0300 Subject: [PATCH 496/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- .../Model/Order/Shipment/Validation/TrackValidatorTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php index 8d050976145..a0c5658e2c9 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php @@ -34,9 +34,9 @@ class TrackValidatorTest extends \PHPUnit_Framework_TestCase { $objectManagerHelper = new ObjectManager($this); $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class) - ->getMock(); + ->getMockForAbstractClass(); $this->shipmentTrackMock = $this->getMockBuilder(ShipmentTrackInterface::class) - ->getMock(); + ->getMockForAbstractClass(); $this->shipmentMock->expects($this->once()) ->method('getTracks') ->willReturn([$this->shipmentTrackMock]); -- GitLab From ff0cb4b5917d361d9ed70cf703827f3c530458f7 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:36:05 +0300 Subject: [PATCH 497/838] MAGETWO-54677: Order status change after Shipment creation through API. Fix gap --- app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php b/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php index 89c92ad80f7..19d06fb0eff 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/CommentCreation.php @@ -91,6 +91,6 @@ class CommentCreation implements ShipmentCommentCreationInterface public function setIsVisibleOnFront($isVisibleOnFront) { $this->isVisibleOnFront = $isVisibleOnFront; - return $isVisibleOnFront; + return $this; } } -- GitLab From 2421db7e626a702afee967e02e83bf76a6abef97 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 18 Aug 2016 16:47:36 +0300 Subject: [PATCH 498/838] MAGETWO-56496: Introduce and implement new ShipOrderInterface --- .../Framework/EntityManager/CustomAttributesMapper.php | 8 +++----- .../Test/Unit/CustomAttributesMapperTest.php | 3 +++ .../Magento/Framework/EntityManager/TypeResolver.php | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php b/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php index 0d350cc122e..fe3a199da86 100644 --- a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php +++ b/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php @@ -55,11 +55,9 @@ class CustomAttributesMapper implements MapperInterface */ public function entityToDatabase($entityType, $data) { - if (!$this->metadataPool->hasConfiguration($entityType)) { - return $data; - } - $metadata = $this->metadataPool->getMetadata($entityType); - if (!$metadata->getEavEntityType()) { + if (!$this->metadataPool->hasConfiguration($entityType) + || !$this->metadataPool->getMetadata($entityType)->getEavEntityType() + ) { return $data; } if (isset($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES])) { diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php index 4c351efd936..56977af1dd6 100644 --- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php +++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php @@ -50,6 +50,9 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['getMetadata', 'hasConfiguration']) ->getMock(); + $metadataPool->expects($this->any()) + ->method('hasConfiguration') + ->willReturn(true); $metadataPool->expects($this->any()) ->method('getMetadata') ->with($this->equalTo(\Magento\Customer\Api\Data\AddressInterface::class)) diff --git a/lib/internal/Magento/Framework/EntityManager/TypeResolver.php b/lib/internal/Magento/Framework/EntityManager/TypeResolver.php index e40eb50595c..2718162e80d 100644 --- a/lib/internal/Magento/Framework/EntityManager/TypeResolver.php +++ b/lib/internal/Magento/Framework/EntityManager/TypeResolver.php @@ -20,7 +20,8 @@ class TypeResolver */ private $typeMapping = [ \Magento\SalesRule\Model\Rule::class => \Magento\SalesRule\Api\Data\RuleInterface::class, - \Magento\SalesRule\Model\Rule\Interceptor::class => \Magento\SalesRule\Api\Data\RuleInterface::class + \Magento\SalesRule\Model\Rule\Interceptor::class => \Magento\SalesRule\Api\Data\RuleInterface::class, + \Magento\SalesRule\Model\Rule\Proxy::class => \Magento\SalesRule\Api\Data\RuleInterface::class ]; /** @@ -50,8 +51,7 @@ class TypeResolver $dataInterfaces = []; foreach ($interfaceNames as $interfaceName) { if (strpos($interfaceName, '\Api\Data\\')) { - $dataInterfaces[] = isset($this->config[$interfaceName]) - ? $this->config[$interfaceName] : $interfaceName; + $dataInterfaces[] = $interfaceName; } } -- GitLab From f89fba5d6d81fbd30faa7085c7cb1a6c13905a1a Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 16:48:20 +0300 Subject: [PATCH 499/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- .../Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 0ca549b9e50..f510544273a 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Sales\Model\Order; use Magento\Sales\Api\Data\ShipmentInterface; @@ -75,7 +74,6 @@ class ShipmentDocumentFactory array $packages = [], ShipmentCreationArgumentsInterface $arguments = null ) { - $shipmentItems = $this->itemsToArray($items); /** @var Shipment $shipment */ $shipment = $this->shipmentFactory->create( @@ -113,12 +111,12 @@ class ShipmentDocumentFactory } /** - * Convert Items To Array + * Convert items to array * * @param ShipmentItemCreationInterface[] $items * @return array */ - private function itemsToArray($items = []) + private function itemsToArray(array $items = []) { $invoiceItems = []; foreach ($items as $item) { -- GitLab From 0788414dc3d3ab982cc5f318878b317ad8e222dc Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Thu, 18 Aug 2016 16:52:20 +0300 Subject: [PATCH 500/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Plugin/PaymentVaultAttributesLoad.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Vault/Plugin/PaymentVaultAttributesLoad.php b/app/code/Magento/Vault/Plugin/PaymentVaultAttributesLoad.php index 810a8c5242d..710b765d11e 100644 --- a/app/code/Magento/Vault/Plugin/PaymentVaultAttributesLoad.php +++ b/app/code/Magento/Vault/Plugin/PaymentVaultAttributesLoad.php @@ -10,6 +10,8 @@ namespace Magento\Vault\Plugin; use Magento\Sales\Api\Data\OrderPaymentExtensionInterface; use Magento\Sales\Api\Data\OrderPaymentInterface; use Magento\Vault\Api\PaymentTokenManagementInterface; +use Magento\Sales\Api\Data\OrderPaymentExtensionFactory; +use Magento\Vault\Api\Data\PaymentTokenInterface; /** * Plugin for loading vault payment extension attribute to order/payment entity @@ -17,7 +19,7 @@ use Magento\Vault\Api\PaymentTokenManagementInterface; class PaymentVaultAttributesLoad { /** - * @var \Magento\Sales\Api\Data\OrderPaymentExtensionFactory + * @var OrderPaymentExtensionFactory */ protected $paymentExtensionFactory; @@ -27,11 +29,11 @@ class PaymentVaultAttributesLoad protected $paymentTokenManagement; /** - * @param \Magento\Sales\Api\Data\OrderPaymentExtensionFactory $paymentExtensionFactory + * @param OrderPaymentExtensionFactory $paymentExtensionFactory * @param PaymentTokenManagement|PaymentTokenManagementInterface $paymentTokenManagement */ public function __construct( - \Magento\Sales\Api\Data\OrderPaymentExtensionFactory $paymentExtensionFactory, + OrderPaymentExtensionFactory $paymentExtensionFactory, PaymentTokenManagementInterface $paymentTokenManagement ) { $this->paymentExtensionFactory = $paymentExtensionFactory; @@ -42,16 +44,13 @@ class PaymentVaultAttributesLoad * Load vault payment extension attribute to order/payment entity * * @param OrderPaymentInterface $payment - * @param \Closure $proceed + * @param OrderPaymentExtensionInterface|null $paymentExtension * @return OrderPaymentExtensionInterface */ - public function aroundGetExtensionAttributes( + public function afterGetExtensionAttributes( OrderPaymentInterface $payment, - \Closure $proceed + OrderPaymentExtensionInterface $paymentExtension = null ) { - /** @var OrderPaymentExtensionInterface $paymentExtension */ - $paymentExtension = $proceed(); - if ($paymentExtension === null) { $paymentExtension = $this->paymentExtensionFactory->create(); } @@ -59,7 +58,7 @@ class PaymentVaultAttributesLoad $paymentToken = $paymentExtension->getVaultPaymentToken(); if ($paymentToken === null) { $paymentToken = $this->paymentTokenManagement->getByPaymentId($payment->getEntityId()); - if ($paymentToken instanceof \Magento\Vault\Api\Data\PaymentTokenInterface) { + if ($paymentToken instanceof PaymentTokenInterface) { $paymentExtension->setVaultPaymentToken($paymentToken); } $payment->setExtensionAttributes($paymentExtension); -- GitLab From 4c20a9bdb66f1c1782324bc4c421db8ed2cc796a Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 17:00:18 +0300 Subject: [PATCH 501/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- .../Sales/Model/Order/Shipment/ShipmentValidator.php | 2 +- .../Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php index 75239253d4c..816551b8b32 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidator.php @@ -18,7 +18,7 @@ class ShipmentValidator implements ShipmentValidatorInterface private $validator; /** - * InvoiceValidatorRunner constructor. + * ShipmentValidator constructor. * @param \Magento\Sales\Model\Validator $validator */ public function __construct(\Magento\Sales\Model\Validator $validator) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php index aabc8a0b08e..b0677b050f6 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ShipmentDocumentFactoryTest.php @@ -18,7 +18,7 @@ use Magento\Sales\Model\Order\Shipment\Track; use Magento\Framework\EntityManager\HydratorInterface; /** - * Class InvoiceDocumentFactoryTest + * Class ShipmentDocumentFactoryTest */ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase { @@ -50,7 +50,7 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase /** * @var ShipmentDocumentFactory */ - private $invoiceDocumentFactory; + private $shipmentDocumentFactory; /** * @var \PHPUnit_Framework_MockObject_MockObject|HydratorPool @@ -112,7 +112,7 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->invoiceDocumentFactory = new ShipmentDocumentFactory( + $this->shipmentDocumentFactory = new ShipmentDocumentFactory( $this->shipmentFactoryMock, $this->hydratorPoolMock, $this->trackFactoryMock @@ -181,7 +181,7 @@ class ShipmentDocumentFactoryTest extends \PHPUnit_Framework_TestCase } $this->assertEquals( - $this->invoiceDocumentFactory->create( + $this->shipmentDocumentFactory->create( $this->orderMock, [$this->itemMock], $tracks, -- GitLab From 90d7f249bec2f20a5f1dffdc932d1ccd7292abb9 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 17:01:36 +0300 Subject: [PATCH 502/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- .../Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index f510544273a..8a553f0d276 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -118,10 +118,10 @@ class ShipmentDocumentFactory */ private function itemsToArray(array $items = []) { - $invoiceItems = []; + $shipmentItems = []; foreach ($items as $item) { - $invoiceItems[$item->getOrderItemId()] = $item->getQty(); + $shipmentItems[$item->getOrderItemId()] = $item->getQty(); } - return $invoiceItems; + return $shipmentItems; } } -- GitLab From 5c8ed158aafc30aed037192debfcd5bfdd1fa58d Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 17:03:26 +0300 Subject: [PATCH 503/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php index 8a553f0d276..d10f84d8155 100644 --- a/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php +++ b/app/code/Magento/Sales/Model/Order/ShipmentDocumentFactory.php @@ -14,8 +14,9 @@ use Magento\Sales\Model\Order\Shipment\TrackFactory; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\ShipmentCommentCreationInterface; use Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface; + /** - * Class InvoiceDocumentFactory + * Class ShipmentDocumentFactory * * @api */ -- GitLab From 13ea6aed63bd9e8b6801c73d4e359c9a8ffa7fd7 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 17:20:47 +0300 Subject: [PATCH 504/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- app/code/Magento/Sales/Model/InvoiceOrder.php | 2 +- app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/InvoiceOrder.php b/app/code/Magento/Sales/Model/InvoiceOrder.php index 63f62cf8ff2..e51b46082d9 100644 --- a/app/code/Magento/Sales/Model/InvoiceOrder.php +++ b/app/code/Magento/Sales/Model/InvoiceOrder.php @@ -24,7 +24,7 @@ use Magento\Sales\Model\Order\Validation\CanInvoice; use Psr\Log\LoggerInterface; /** - * Class InvoiceService + * Class InvoiceOrder * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class InvoiceOrder implements InvoiceOrderInterface diff --git a/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php index 5c3283bc155..6dfa929acb6 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php @@ -26,6 +26,7 @@ use Psr\Log\LoggerInterface; /** * Class InvoiceOrderTest + * * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -- GitLab From e4c020fe5840d262730318b277d019ba3999a611 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 18 Aug 2016 17:38:26 +0300 Subject: [PATCH 505/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Sales/Model/Order/Shipment/Validation/TrackValidator.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php index 8ba20542da1..1d7fad1e2aa 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php @@ -20,6 +20,9 @@ class TrackValidator implements ValidatorInterface public function validate($entity) { $messages = []; + if ($entity->getTracks()) { + return $messages; + } foreach ($entity->getTracks() as $track) { if (!$track->getTrackNumber()) { $messages[] = __('Please enter a tracking number.'); -- GitLab From 5cef44b40afdf2a0900fe29a0b1b45730d348ae7 Mon Sep 17 00:00:00 2001 From: Anton Kaplya <anton.kaplya@magento.com> Date: Thu, 18 Aug 2016 17:40:19 +0300 Subject: [PATCH 506/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Sales/Model/Order/Shipment/Validation/TrackValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php index 1d7fad1e2aa..55970d37c59 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php +++ b/app/code/Magento/Sales/Model/Order/Shipment/Validation/TrackValidator.php @@ -20,7 +20,7 @@ class TrackValidator implements ValidatorInterface public function validate($entity) { $messages = []; - if ($entity->getTracks()) { + if (!$entity->getTracks()) { return $messages; } foreach ($entity->getTracks() as $track) { -- GitLab From 995489eaae810574651f2fb05b226751d44a10f9 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Thu, 18 Aug 2016 17:53:57 +0300 Subject: [PATCH 507/838] MAGETWO-56819: Notification messages area. Pull request preparation. --- app/code/Magento/AdminNotification/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json index 0a29908b77f..527268df36b 100644 --- a/app/code/Magento/AdminNotification/composer.json +++ b/app/code/Magento/AdminNotification/composer.json @@ -7,6 +7,7 @@ "magento/module-backend": "100.2.*", "magento/module-media-storage": "100.2.*", "magento/framework": "100.2.*", + "magento/module-ui": "100.2.*", "lib-libxml": "*" }, "type": "magento2-module", -- GitLab From 69dd3f5cb32d06afcec19352260d618bac334f10 Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Thu, 18 Aug 2016 18:07:19 +0300 Subject: [PATCH 508/838] MAGETWO-54054: Compiler performance optimization - MAGETWO-57139: Improve search of paths which should be excluded from compilation - all regexps for each module joined in single one --- .../Console/Command/DiCompileCommand.php | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index 820adde7d74..a43fca91145 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -205,10 +205,31 @@ class DiCompileCommand extends Command */ private function getExcludedModulePaths($modulePaths) { - $excludedModulePaths = []; - foreach ($modulePaths as $appCodePath) { - $excludedModulePaths[] = '#^' . $appCodePath . '/Test#'; + $modulesByBasePath = []; + foreach ($modulePaths as $modulePath) { + $moduleDir = basename($modulePath); + $vendorPath = dirname($modulePath); + $vendorDir = basename($vendorPath); + $basePath = dirname($vendorPath); + $modulesByBasePath[$basePath][$vendorDir][] = $moduleDir; } + + $basePathsRegExps = []; + foreach ($modulesByBasePath as $basePath => $vendorPaths) { + $vendorPathsRegExps = []; + foreach ($vendorPaths as $vendorDir => $vendorModules) { + $vendorPathsRegExps[] = $vendorDir + . DIRECTORY_SEPARATOR + . '(?:' . join('|', $vendorModules) . ')'; + } + $basePathsRegExps[] = $basePath + . DIRECTORY_SEPARATOR + . '(?:' . join('|', $vendorPathsRegExps) . ')'; + } + + $excludedModulePaths = [ + '#^(?:' . join('|', $basePathsRegExps) . ')/Test#', + ]; return $excludedModulePaths; } @@ -220,10 +241,9 @@ class DiCompileCommand extends Command */ private function getExcludedLibraryPaths($libraryPaths) { - $excludedLibraryPaths = []; - foreach ($libraryPaths as $libraryPath) { - $excludedLibraryPaths[] = '#^' . $libraryPath . '/([\\w]+/)?Test#'; - } + $excludedLibraryPaths = [ + '#^(?:' . join('|', $libraryPaths) . ')/([\\w]+/)?Test#', + ]; return $excludedLibraryPaths; } -- GitLab From b95b1a617e42577c50f0dc83f3995918f35e23ae Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 18:10:49 +0300 Subject: [PATCH 509/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- app/code/Magento/Sales/etc/di.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index 2fd8f789a35..f1b2c083b44 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -92,7 +92,6 @@ <preference for="Magento\Sales\Model\Spi\ShipmentTrackResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Track"/> <preference for="Magento\Sales\Model\Spi\TransactionResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Payment\Transaction"/> <preference for="Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface" type="Magento\Sales\Model\ResourceModel\Order\CollectionFactory"/> - <preference for="Magento\Sales\Api\Data\InvoiceCommentCreationInterface" type="Magento\Sales\Model\Order\Invoice\Comment"/> <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> <preference for="Magento\Sales\Api\InvoiceOrderInterface" type="Magento\Sales\Model\InvoiceOrder"/> <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> -- GitLab From 95c6b6ec544b850ecbda8cef893cc67f3b094338 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 18:15:30 +0300 Subject: [PATCH 510/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- .../Shipping/Controller/Adminhtml/Order/Shipment/Save.php | 4 ++-- .../Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index 9be027576c2..a615ffa5c3a 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -8,7 +8,7 @@ namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; use Magento\Framework\App\ObjectManager; -use Magento\Sales\Model\Order\ShipmentQuantityValidator; +use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator; /** * Class Save @@ -129,7 +129,7 @@ class Save extends \Magento\Backend\App\Action $shipment->setCustomerNote($data['comment_text']); $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify'])); } - $errorMessages = $this->getShipmentValidator()->validate($shipment, [ShipmentQuantityValidator::class]); + $errorMessages = $this->getShipmentValidator()->validate($shipment, [QuantityValidator::class]); if (!empty($errorMessages)) { $this->messageManager->addError( __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages)) diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php index bdc4dd17d10..f8d9c06dc8e 100644 --- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php @@ -12,7 +12,7 @@ use Magento\Backend\App\Action; use Magento\Sales\Model\Order\Email\Sender\ShipmentSender; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface; -use Magento\Sales\Model\Order\ShipmentQuantityValidator; +use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator; /** * Class SaveTest @@ -361,7 +361,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase $this->shipmentValidatorMock->expects($this->once()) ->method('validate') - ->with($shipment, [ShipmentQuantityValidator::class]) + ->with($shipment, [QuantityValidator::class]) ->willReturn([]); $this->saveAction->execute(); -- GitLab From 044a5182bb0aa6b28589c878084840260c5012f3 Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 18:26:28 +0300 Subject: [PATCH 511/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- app/code/Magento/Sales/etc/di.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml index f1b2c083b44..dfdb0f6a261 100644 --- a/app/code/Magento/Sales/etc/di.xml +++ b/app/code/Magento/Sales/etc/di.xml @@ -92,7 +92,6 @@ <preference for="Magento\Sales\Model\Spi\ShipmentTrackResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Shipment\Track"/> <preference for="Magento\Sales\Model\Spi\TransactionResourceInterface" type="Magento\Sales\Model\ResourceModel\Order\Payment\Transaction"/> <preference for="Magento\Sales\Model\ResourceModel\Order\CollectionFactoryInterface" type="Magento\Sales\Model\ResourceModel\Order\CollectionFactory"/> - <preference for="Magento\Sales\Api\Data\InvoiceItemCreationInterface" type="Magento\Sales\Model\Order\Invoice\ItemCreation"/> <preference for="Magento\Sales\Api\InvoiceOrderInterface" type="Magento\Sales\Model\InvoiceOrder"/> <preference for="Magento\Sales\Model\Order\OrderStateResolverInterface" type="Magento\Sales\Model\Order\StateResolver"/> <preference for="Magento\Sales\Api\Data\ShipmentTrackCreationInterface" type="Magento\Sales\Model\Order\Shipment\TrackCreation"/> -- GitLab From 5239bf9aa60d461da4c8af58cc2f9670ddbe2101 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Thu, 18 Aug 2016 18:28:54 +0300 Subject: [PATCH 512/838] MAGETWO-56778: Value for multiple select attribute does not save --- app/code/Magento/Catalog/Model/ResourceModel/Product.php | 2 +- app/code/Magento/Eav/Model/Entity/AbstractEntity.php | 5 ++--- app/code/Magento/Eav/Model/Entity/Attribute.php | 1 + .../Framework/EntityManager/Observer/AfterEntitySave.php | 3 --- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product.php b/app/code/Magento/Catalog/Model/ResourceModel/Product.php index 96688766582..a3be4a2f98a 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product.php @@ -567,7 +567,7 @@ class Product extends AbstractResource */ public function load($object, $entityId, $attributes = []) { - $this->loadAttributesMetadata($attributes, $object); + $this->loadAttributesMetadata($attributes); $this->getEntityManager()->load($object, $entityId); return $this; } diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index 506cf0c9680..c3e5a4b0c4d 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -975,13 +975,12 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac * Loads attributes metadata. * * @param array|null $attributes - * @param null|\Magento\Framework\DataObject $object * @return $this */ - protected function loadAttributesMetadata($attributes, $object = null) + protected function loadAttributesMetadata($attributes) { if (empty($attributes)) { - $this->loadAllAttributes($object); + $this->loadAllAttributes(); } else { if (!is_array($attributes)) { $attributes = [$attributes]; diff --git a/app/code/Magento/Eav/Model/Entity/Attribute.php b/app/code/Magento/Eav/Model/Entity/Attribute.php index 528dee5f239..b9ae0103ca9 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute.php @@ -498,6 +498,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute im */ public function __sleep() { + $this->unsetData('attribute_set_info'); return array_diff( parent::__sleep(), ['_localeDate', '_localeResolver', 'reservedAttributeList', 'dateTimeFormatter'] diff --git a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php index dda098df179..da9ae0e7ddf 100644 --- a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php +++ b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php @@ -27,9 +27,6 @@ class AfterEntitySave implements ObserverInterface { $entity = $observer->getEvent()->getEntity(); if ($entity instanceof AbstractModel) { - if (method_exists($entity->getResource(), 'loadAllAttributes')) { - $entity->getResource()->loadAllAttributes($entity); - } $entity->getResource()->afterSave($entity); $entity->afterSave(); $entity->getResource()->addCommitCallback([$entity, 'afterCommitCallback']); -- GitLab From 9e9b7aa0e80d735e291d91c72df40a927fa3d45e Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 18:33:13 +0300 Subject: [PATCH 513/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- .../Validation/TrackValidatorTest.php | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php index a0c5658e2c9..0d8d951ccf1 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/TrackValidatorTest.php @@ -37,9 +37,6 @@ class TrackValidatorTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $this->shipmentTrackMock = $this->getMockBuilder(ShipmentTrackInterface::class) ->getMockForAbstractClass(); - $this->shipmentMock->expects($this->once()) - ->method('getTracks') - ->willReturn([$this->shipmentTrackMock]); $this->validator = $objectManagerHelper->getObject(TrackValidator::class); } @@ -48,6 +45,9 @@ class TrackValidatorTest extends \PHPUnit_Framework_TestCase $this->shipmentTrackMock->expects($this->once()) ->method('getTrackNumber') ->willReturn('12345'); + $this->shipmentMock->expects($this->exactly(2)) + ->method('getTracks') + ->willReturn([$this->shipmentTrackMock]); $this->assertEquals([], $this->validator->validate($this->shipmentMock)); } @@ -56,6 +56,19 @@ class TrackValidatorTest extends \PHPUnit_Framework_TestCase $this->shipmentTrackMock->expects($this->once()) ->method('getTrackNumber') ->willReturn(null); + $this->shipmentMock->expects($this->exactly(2)) + ->method('getTracks') + ->willReturn([$this->shipmentTrackMock]); $this->assertEquals([__('Please enter a tracking number.')], $this->validator->validate($this->shipmentMock)); } -} \ No newline at end of file + + public function testValidateTrackWithEmptyTracks() + { + $this->shipmentTrackMock->expects($this->never()) + ->method('getTrackNumber'); + $this->shipmentMock->expects($this->once()) + ->method('getTracks') + ->willReturn([]); + $this->assertEquals([], $this->validator->validate($this->shipmentMock)); + } +} -- GitLab From 2621d002d264baa3f189e36ac6571051205e6cdf Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Thu, 18 Aug 2016 18:44:58 +0300 Subject: [PATCH 514/838] MAGETWO-54677: Order status change after Shipment creation through API. Static fixes --- app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php index c0f2771561e..bb14dc1bb51 100644 --- a/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php +++ b/app/code/Magento/Sales/Model/Order/Validation/CanInvoice.php @@ -31,6 +31,10 @@ class CanInvoice implements ValidatorInterface return $messages; } + /** + * @param OrderInterface $order + * @return bool + */ private function isStateReadyForInvoice(OrderInterface $order) { if ($order->getState() === Order::STATE_PAYMENT_REVIEW || -- GitLab From 71118994c9c937472df1c5db9230b3c0569d2332 Mon Sep 17 00:00:00 2001 From: Volodymyr Kublytskyi <vkublytskyi@magento.com> Date: Thu, 18 Aug 2016 18:45:09 +0300 Subject: [PATCH 515/838] MAGETWO-54054: Compiler performance optimization - MAGETWO-57139: Improve search of paths which should be excluded from compilation - fixed directory separator --- .../src/Magento/Setup/Console/Command/DiCompileCommand.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index a43fca91145..a1ad9bab5b2 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -219,12 +219,10 @@ class DiCompileCommand extends Command $vendorPathsRegExps = []; foreach ($vendorPaths as $vendorDir => $vendorModules) { $vendorPathsRegExps[] = $vendorDir - . DIRECTORY_SEPARATOR - . '(?:' . join('|', $vendorModules) . ')'; + . '/(?:' . join('|', $vendorModules) . ')'; } $basePathsRegExps[] = $basePath - . DIRECTORY_SEPARATOR - . '(?:' . join('|', $vendorPathsRegExps) . ')'; + . '/(?:' . join('|', $vendorPathsRegExps) . ')'; } $excludedModulePaths = [ -- GitLab From b7943bddb05a8efeb365f08a8df57ea88d5696c1 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Thu, 18 Aug 2016 19:05:45 +0300 Subject: [PATCH 516/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Theme/Model/Url/Plugin/Signature.php | 7 ++--- .../Unit/Model/Url/Plugin/SignatureTest.php | 18 +++--------- .../Weee/Model/App/Action/ContextPlugin.php | 13 ++++----- .../Unit/App/Action/ContextPluginTest.php | 28 ++++++------------- 4 files changed, 20 insertions(+), 46 deletions(-) diff --git a/app/code/Magento/Theme/Model/Url/Plugin/Signature.php b/app/code/Magento/Theme/Model/Url/Plugin/Signature.php index 2a4d878e80d..8934c598feb 100644 --- a/app/code/Magento/Theme/Model/Url/Plugin/Signature.php +++ b/app/code/Magento/Theme/Model/Url/Plugin/Signature.php @@ -47,7 +47,7 @@ class Signature * Append signature to rendered base URL for static view files * * @param \Magento\Framework\Url\ScopeInterface $subject - * @param callable $proceed + * @param string $baseUrl * @param string $type * @param null $secure * @return string @@ -55,13 +55,12 @@ class Signature * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundGetBaseUrl( + public function afterGetBaseUrl( \Magento\Framework\Url\ScopeInterface $subject, - \Closure $proceed, + $baseUrl, $type = \Magento\Framework\UrlInterface::URL_TYPE_LINK, $secure = null ) { - $baseUrl = $proceed($type, $secure); if ($type == \Magento\Framework\UrlInterface::URL_TYPE_STATIC && $this->isUrlSignatureEnabled()) { $baseUrl .= $this->renderUrlSignature() . '/'; } diff --git a/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php b/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php index 46097a13db1..31dd9af4771 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php @@ -4,8 +4,6 @@ * See COPYING.txt for license details. */ -// @codingStandardsIgnoreFile - namespace Magento\Theme\Test\Unit\Model\Url\Plugin; use \Magento\Theme\Model\Url\Plugin\Signature; @@ -27,20 +25,12 @@ class SignatureTest extends \PHPUnit_Framework_TestCase */ private $deploymentVersion; - /** - * @var callable - */ - private $closureMock; - protected function setUp() { $this->config = $this->getMock(\Magento\Framework\View\Url\ConfigInterface::class); - $this->deploymentVersion = $this->getMock( + $this->deploymentVersion = $this->getMock( \Magento\Framework\App\View\Deployment\Version::class, [], [], '', false ); - $this->closureMock = function () { - return 'http://127.0.0.1/magento/pub/static/'; - }; $this->object = new Signature($this->config, $this->deploymentVersion); } @@ -59,7 +49,7 @@ class SignatureTest extends \PHPUnit_Framework_TestCase $this->deploymentVersion->expects($this->never())->method($this->anything()); $url = $this->getMockForAbstractClass(\Magento\Framework\Url\ScopeInterface::class); - $actualResult = $this->object->aroundGetBaseUrl($url, $this->closureMock, $inputUrlType); + $actualResult = $this->object->afterGetBaseUrl($url, 'http://127.0.0.1/magento/pub/static/', $inputUrlType); $this->assertEquals('http://127.0.0.1/magento/pub/static/', $actualResult); } @@ -81,8 +71,8 @@ class SignatureTest extends \PHPUnit_Framework_TestCase $this->deploymentVersion->expects($this->once())->method('getValue')->will($this->returnValue('123')); $url = $this->getMockForAbstractClass(\Magento\Framework\Url\ScopeInterface::class); - $actualResult = $this->object->aroundGetBaseUrl( - $url, $this->closureMock, \Magento\Framework\UrlInterface::URL_TYPE_STATIC + $actualResult = $this->object->afterGetBaseUrl( + $url, 'http://127.0.0.1/magento/pub/static/', \Magento\Framework\UrlInterface::URL_TYPE_STATIC ); $this->assertEquals('http://127.0.0.1/magento/pub/static/version123/', $actualResult); } diff --git a/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php b/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php index c00f2f3491e..43344c196ec 100644 --- a/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php @@ -92,29 +92,27 @@ class ContextPlugin /** * @param \Magento\Framework\App\ActionInterface $subject - * @param callable $proceed * @param \Magento\Framework\App\RequestInterface $request - * @return mixed + * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function aroundDispatch( + public function beforeDispatch( \Magento\Framework\App\ActionInterface $subject, - \Closure $proceed, \Magento\Framework\App\RequestInterface $request ) { if (!$this->weeeHelper->isEnabled() || !$this->customerSession->isLoggedIn() || !$this->moduleManager->isEnabled('Magento_PageCache') || !$this->cacheConfig->isEnabled()) { - return $proceed($request); + return; } $basedOn = $this->taxHelper->getTaxBasedOn(); if ($basedOn != 'shipping' && $basedOn != 'billing') { - return $proceed($request); + return; } $weeeTaxRegion = $this->getWeeeTaxRegion($basedOn); @@ -124,7 +122,7 @@ class ContextPlugin if (!$countryId && !$regionId) { // country and region does not exist - return $proceed($request); + return; } else if ($countryId && !$regionId) { // country exist and region does not exist $regionId = 0; @@ -158,7 +156,6 @@ class ContextPlugin 0 ); } - return $proceed($request); } /** diff --git a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php index ebb0837d3c1..95694b9386d 100644 --- a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php @@ -187,11 +187,8 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $action = $this->objectManager->getObject(\Magento\Framework\App\Test\Unit\Action\Stub\ActionStub::class); $request = $this->getMock(\Magento\Framework\App\Request\Http::class, ['getActionName'], [], '', false); - $expectedResult = 'expectedResult'; - $proceed = function ($request) use ($expectedResult) { - return $expectedResult; - }; - $this->contextPlugin->aroundDispatch($action, $proceed, $request); + + $this->contextPlugin->beforeDispatch($action, $request); } public function testAroundDispatchBasedOnOrigin() @@ -219,11 +216,8 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $action = $this->objectManager->getObject(\Magento\Framework\App\Test\Unit\Action\Stub\ActionStub::class); $request = $this->getMock(\Magento\Framework\App\Request\Http::class, ['getActionName'], [], '', false); - $expectedResult = 'expectedResult'; - $proceed = function ($request) use ($expectedResult) { - return $expectedResult; - }; - $this->contextPlugin->aroundDispatch($action, $proceed, $request); + + $this->contextPlugin->beforeDispatch($action, $request); } public function testAroundDispatchBasedOnBilling() @@ -294,11 +288,8 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $action = $this->objectManager->getObject(\Magento\Framework\App\Test\Unit\Action\Stub\ActionStub::class); $request = $this->getMock(\Magento\Framework\App\Request\Http::class, ['getActionName'], [], '', false); - $expectedResult = 'expectedResult'; - $proceed = function ($request) use ($expectedResult) { - return $expectedResult; - }; - $this->contextPlugin->aroundDispatch($action, $proceed, $request); + + $this->contextPlugin->beforeDispatch($action, $request); } public function testAroundDispatchBasedOnShipping() @@ -369,10 +360,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $action = $this->objectManager->getObject(\Magento\Framework\App\Test\Unit\Action\Stub\ActionStub::class); $request = $this->getMock(\Magento\Framework\App\Request\Http::class, ['getActionName'], [], '', false); - $expectedResult = 'expectedResult'; - $proceed = function ($request) use ($expectedResult) { - return $expectedResult; - }; - $this->contextPlugin->aroundDispatch($action, $proceed, $request); + + $this->contextPlugin->beforeDispatch($action, $request); } } -- GitLab From d7111057d639242576791fa5df04d78dfcfd9cf5 Mon Sep 17 00:00:00 2001 From: vnayda <vnayda@magento.com> Date: Thu, 18 Aug 2016 19:26:44 +0300 Subject: [PATCH 517/838] MAGETWO-56778: Value for multiple select attribute does not save --- .../Framework/EntityManager/Observer/AfterEntitySave.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php index da9ae0e7ddf..9ca4a894739 100644 --- a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php +++ b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntitySave.php @@ -27,6 +27,9 @@ class AfterEntitySave implements ObserverInterface { $entity = $observer->getEvent()->getEntity(); if ($entity instanceof AbstractModel) { + if (method_exists($entity->getResource(), 'loadAllAttributes')) { + $entity->getResource()->loadAllAttributes(); + } $entity->getResource()->afterSave($entity); $entity->afterSave(); $entity->getResource()->addCommitCallback([$entity, 'afterCommitCallback']); -- GitLab From 9e83385392cf37e89264f3f15ffd66698cda6cb6 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 18 Aug 2016 12:18:47 -0500 Subject: [PATCH 518/838] MAGETWO-55928: Eliminate @escapeNotVerified in Widget Module --- .../Magento/Catalog/Block/Adminhtml/Category/Widget/Chooser.php | 2 +- .../Magento/Catalog/Block/Adminhtml/Product/Widget/Chooser.php | 2 +- .../view/adminhtml/templates/catalog/category/widget/tree.phtml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Widget/Chooser.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Widget/Chooser.php index 172d1cf65d2..95541d864b8 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Widget/Chooser.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Widget/Chooser.php @@ -121,7 +121,7 @@ class Chooser extends \Magento\Catalog\Block\Adminhtml\Category\Tree } '; } else { - $chooserJsObject = $this->getId(); + $chooserJsObject = $this->escapeJs($this->getId()); $js = ' function (node, e) { ' . diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Widget/Chooser.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Widget/Chooser.php index 7012a80ed93..ee6d75ff927 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Widget/Chooser.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Widget/Chooser.php @@ -202,7 +202,7 @@ class Chooser extends Extended {jsObject}.categoryName = node.attributes.id != "none" ? node.text : false; } '; - $js = str_replace('{jsObject}', $this->getJsObjectName(), $js); + $js = str_replace('{jsObject}', $this->escapeJs($this->getJsObjectName()), $js); return $js; } diff --git a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml index 5533074de13..4e240770b04 100644 --- a/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml +++ b/app/code/Magento/Widget/view/adminhtml/templates/catalog/category/widget/tree.phtml @@ -44,7 +44,7 @@ Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, { if (firstLoad) { <?php if ($block->getNodeClickListener()): ?> - this.addListener('click', <?php echo $block->escapeHtml($block->getNodeClickListener()) ?>.createDelegate(this)); + this.addListener('click', <?php /* @noEscape */ echo $block->getNodeClickListener() ?>.createDelegate(this)); <?php endif; ?> } -- GitLab From efb6455bd70c97c76d54db87c01725b700b80a8c Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 18 Aug 2016 15:37:44 -0500 Subject: [PATCH 519/838] MAGETWO-56868: CLONE - Cannot save a product with images for the second time - Fixed image merging problem. --- app/code/Magento/Catalog/Model/Product.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index b1fbe6aed93..603e566f14f 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -1468,7 +1468,10 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements if (!$this->hasData('media_gallery_images') && is_array($this->getMediaGallery('images'))) { $images = $this->_collectionFactory->create(); foreach ($this->getMediaGallery('images') as $image) { - if ((isset($image['disabled']) && $image['disabled']) || empty($image['value_id'])) { + if ((isset($image['disabled']) && $image['disabled']) + || empty($image['value_id']) + || $images->getItemById($image['value_id']) != null + ) { continue; } $image['url'] = $this->getMediaConfig()->getMediaUrl($image['file']); -- GitLab From dd658947b277c7d4fd529d734521cc9ce2953acc Mon Sep 17 00:00:00 2001 From: Alex Paliarush <apaliarush@magento.com> Date: Thu, 18 Aug 2016 15:43:04 -0500 Subject: [PATCH 520/838] MAGETWO-54460: Admin user with access to only one website is unable to edit a product --- .../CatalogRule/Model/Indexer/IndexBuilder.php | 8 ++++++-- .../Rule/Collection/AbstractCollection.php | 11 +++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php index 190a5c24fce..e716f3c1011 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php @@ -159,7 +159,9 @@ class IndexBuilder $this->doReindexByIds($ids); } catch (\Exception $e) { $this->critical($e); - throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()), $e); + throw new \Magento\Framework\Exception\LocalizedException( + __("Catalog rule indexing failed. See details in exception log.") + ); } } @@ -193,7 +195,9 @@ class IndexBuilder $this->doReindexFull(); } catch (\Exception $e) { $this->critical($e); - throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()), $e); + throw new \Magento\Framework\Exception\LocalizedException( + __("Catalog rule indexing failed. See details in exception log.") + ); } } diff --git a/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php b/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php index 31867d2f270..905bd68e308 100644 --- a/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php +++ b/app/code/Magento/Rule/Model/ResourceModel/Rule/Collection/AbstractCollection.php @@ -74,15 +74,18 @@ abstract class AbstractCollection extends \Magento\Framework\Model\ResourceModel */ public function addWebsiteFilter($websiteId) { - $entityInfo = $this->_getAssociatedEntityInfo('website'); if (!$this->getFlag('is_website_table_joined')) { + $websiteIds = is_array($websiteId) ? $websiteId : [$websiteId]; + $entityInfo = $this->_getAssociatedEntityInfo('website'); $this->setFlag('is_website_table_joined', true); - if ($websiteId instanceof \Magento\Store\Model\Website) { - $websiteId = $websiteId->getId(); + foreach ($websiteIds as $index => $website) { + if ($website instanceof \Magento\Store\Model\Website) { + $websiteIds[$index] = $website->getId(); + } } $this->getSelect()->join( ['website' => $this->getTable($entityInfo['associations_table'])], - $this->getConnection()->quoteInto('website.' . $entityInfo['entity_id_field'] . ' = ?', $websiteId) + $this->getConnection()->quoteInto('website.' . $entityInfo['entity_id_field'] . ' IN (?)', $websiteIds) . ' AND main_table.' . $entityInfo['rule_id_field'] . ' = website.' . $entityInfo['rule_id_field'], [] ); -- GitLab From eb5422a06ee7927a098382fea1fa1abb575547d8 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 18 Aug 2016 15:49:08 -0500 Subject: [PATCH 521/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 #5225 - modifying logic and unit test according to resolved logic agreed, only new products should select default value --- .../Product/Form/Modifier/EavTest.php | 33 ++++++++++-------- .../Product/Form/Modifier/Eav.php | 34 ++----------------- .../view/base/web/js/form/element/select.js | 26 ++++++++++---- 3 files changed, 40 insertions(+), 53 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index f7ef45563d2..f7a48b68015 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -182,7 +182,6 @@ class EavTest extends AbstractModifierTest */ protected $eventManagerMock; - /** * @var ObjectManager */ @@ -193,6 +192,9 @@ class EavTest extends AbstractModifierTest */ protected $eav; + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ protected function setUp() { parent::setUp(); @@ -466,13 +468,14 @@ class EavTest extends AbstractModifierTest $this->productMock->expects($this->any()) ->method('getId') ->willReturn($productId); + $this->productAttributeMock->expects($this->any()) ->method('getIsRequired') ->willReturn($productRequired); $this->productAttributeMock->expects($this->any()) ->method('getDefaultValue') - ->willReturn($productRequired? 'required_value' : null); + ->willReturn('required_value'); $this->productAttributeMock->expects($this->any()) ->method('getAttributeCode') @@ -529,14 +532,14 @@ class EavTest extends AbstractModifierTest 'default_null_prod_not_new_and_required' => [ 'productId' => 1, 'productRequired' => true, - 'attrValue' => null, + 'attrValue' => 'val', 'expected' => [ 'dataType' => null, 'formElement' => null, 'visible' => null, 'required' => true, 'notice' => null, - 'default' => 'required_value', + 'default' => null, 'label' => null, 'code' => 'code', 'source' => 'product-details', @@ -545,15 +548,15 @@ class EavTest extends AbstractModifierTest 'sortOrder' => 0 ], ], - 'default_null_prod_not_new_and_required_with_value' => [ + 'default_null_prod_not_new_and_not_required' => [ 'productId' => 1, - 'productRequired' => true, + 'productRequired' => false, 'attrValue' => 'val', 'expected' => [ 'dataType' => null, 'formElement' => null, 'visible' => null, - 'required' => true, + 'required' => false, 'notice' => null, 'default' => null, 'label' => null, @@ -562,10 +565,10 @@ class EavTest extends AbstractModifierTest 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0 + ], ], - ], - 'default_null_prod_not_new_and_not_required_no_value' => [ - 'productId' => 1, + 'default_null_prod_new_and_not_required' => [ + 'productId' => null, 'productRequired' => false, 'attrValue' => null, 'expected' => [ @@ -574,7 +577,7 @@ class EavTest extends AbstractModifierTest 'visible' => null, 'required' => false, 'notice' => null, - 'default' => null, + 'default' => 'required_value', 'label' => null, 'code' => 'code', 'source' => 'product-details', @@ -583,15 +586,15 @@ class EavTest extends AbstractModifierTest 'sortOrder' => 0 ], ], - 'default_null_prod_NEW_no_value' => [ + 'default_null_prod_new_and_required' => [ 'productId' => null, - 'productRequired' => true, + 'productRequired' => false, 'attrValue' => null, 'expected' => [ 'dataType' => null, 'formElement' => null, 'visible' => null, - 'required' => true, + 'required' => false, 'notice' => null, 'default' => 'required_value', 'label' => null, @@ -601,7 +604,7 @@ class EavTest extends AbstractModifierTest 'globalScope' => false, 'sortOrder' => 0 ], - ], + ] ]; } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index e60d459dbcf..1419c17e11b 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -527,41 +527,11 @@ class Eav extends AbstractModifier * * @return bool */ - private function isProductNew() + private function isProductExists() { return (bool) $this->locator->getProduct()->getId(); } - /** - * Check is product has some value for attribute - * - * @param ProductAttributeInterface $attribute - * @return bool - */ - private function isProductHasValueForAttribute(ProductAttributeInterface $attribute) - { - /** @var \Magento\Framework\Api\AttributeInterface $attributeCode */ - $attributeCode = $this->locator->getProduct()->getCustomAttribute($attribute->getAttributeCode()); - return (bool)($attributeCode !== null) && $attributeCode->getValue(); - } - - /** - * Check should we display default values for attribute or not - * - * @param ProductAttributeInterface $attribute - * @return bool - */ - private function isShowDefaultValue(ProductAttributeInterface $attribute) - { - if (!$this->isProductNew()) { - return true; - } elseif ($attribute->getIsRequired() && !$this->isProductHasValueForAttribute($attribute)) { - return true; - } - - return false; - } - /** * Initial meta setup * @@ -584,7 +554,7 @@ class Eav extends AbstractModifier 'visible' => $attribute->getIsVisible(), 'required' => $attribute->getIsRequired(), 'notice' => $attribute->getNote(), - 'default' => $this->isShowDefaultValue($attribute) ? $attribute->getDefaultValue() : null, + 'default' => (!$this->isProductExists()) ? $attribute->getDefaultValue() : null, 'label' => $attribute->getDefaultFrontendLabel(), 'code' => $attribute->getAttributeCode(), 'source' => $groupCode, diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/select.js b/app/code/Magento/Ui/view/base/web/js/form/element/select.js index ef869965e35..1887639c8d0 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/select.js @@ -44,9 +44,9 @@ define([ if (_.isUndefined(caption)) { caption = node.label; } - } else { - return node; } + + return node; }); return { @@ -163,10 +163,6 @@ define([ this.observe('options') .setOptions(this.options()); - if (_.isUndefined(this.value()) && !this.default) { - this.clear(); - } - return this; }, @@ -290,6 +286,11 @@ define([ return preview; }, + /** + * + * @param {Number} value + * @returns {Object} Chainable + */ getOption: function (value) { return this.indexedOptions[value]; }, @@ -305,6 +306,19 @@ define([ this.value(value); return this; + }, + + /** + * Initializes observable properties of instance + * + * @returns {Object} Chainable. + */ + setInitialValue: function () { + if (_.isUndefined(this.value()) && !this.default) { + this.clear(); + } + + return this._super(); } }); }); -- GitLab From b97e3a361f623cee80ccdee867f4213918aef586 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 18 Aug 2016 16:00:23 -0500 Subject: [PATCH 522/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 #5225 - fix code integrity test --- .../Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index f7a48b68015..e2b47aa9538 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -453,9 +453,7 @@ class EavTest extends AbstractModifierTest * @param bool $productRequired * @param string $attrValue * @param array $expected - * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isProductNew - * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isProductHasValueForAttribute - * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isShowDefaultValue + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isProductExists * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::setupAttributeMeta * @dataProvider setupAttributeMetaDataProvider */ -- GitLab From 93688009abfb35adc57600d62925a2c0d15bb24c Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 18 Aug 2016 16:10:51 -0500 Subject: [PATCH 523/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 #5225 - fix code integrity test --- .../Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index e2b47aa9538..2deb4800bd0 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -453,8 +453,8 @@ class EavTest extends AbstractModifierTest * @param bool $productRequired * @param string $attrValue * @param array $expected - * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::isProductExists - * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier::setupAttributeMeta + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav::isProductExists + * @covers \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav::setupAttributeMeta * @dataProvider setupAttributeMetaDataProvider */ public function testSetupAttributeMetaDefaultAttribute($productId, $productRequired, $attrValue, $expected) -- GitLab From 450823144272332b002eaf3fe778ba548109e115 Mon Sep 17 00:00:00 2001 From: Olexandr Lysenko <olysenko@magento.com> Date: Fri, 19 Aug 2016 10:26:27 +0300 Subject: [PATCH 524/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Magento/Sales/Service/V1/OrderInvoiceCreateTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php index cb384134a7c..60c9f54ea13 100644 --- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderInvoiceCreateTest.php @@ -10,7 +10,7 @@ namespace Magento\Sales\Service\V1; */ class OrderInvoiceCreateTest extends \Magento\TestFramework\TestCase\WebapiAbstract { - const SERVICE_READ_NAME = 'salesOrderInvoiceV1'; + const SERVICE_READ_NAME = 'salesInvoiceOrderV1'; const SERVICE_VERSION = 'V1'; /** -- GitLab From 8ed5fe465a56974b87cb32abbd729b2b07b3a375 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 19 Aug 2016 11:28:03 +0300 Subject: [PATCH 525/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- setup/pub/magento/setup/select-version.js | 16 ++-- .../src/Magento/Setup/Model/SystemPackage.php | 73 +++++++++++++++++++ 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/setup/pub/magento/setup/select-version.js b/setup/pub/magento/setup/select-version.js index cc338f05489..cd01b9ee861 100644 --- a/setup/pub/magento/setup/select-version.js +++ b/setup/pub/magento/setup/select-version.js @@ -49,8 +49,11 @@ angular.module('select-version', ['ngStorage']) $scope.currentVersion = value.name; } }); - $scope.selectedOption = $scope.versions[0].versionInfo; - $scope.upgradeReadyForNext = true; + + if ($scope.versions.length > 0) { + $scope.selectedOption = $scope.versions[0].versionInfo; + $scope.upgradeReadyForNext = true; + } } } else { @@ -170,9 +173,12 @@ angular.module('select-version', ['ngStorage']) }); } }); - $scope.selectedOption = $scope.versions[0].versionInfo; - $scope.upgradeReadyForNext = true; - } + + if ($scope.versions.length > 0) { + $scope.selectedOption = $scope.versions[0].versionInfo; + $scope.upgradeReadyForNext = true; + } + }; $scope.update = function() { var selectedVersionInfo = angular.fromJson($scope.selectedOption); diff --git a/setup/src/Magento/Setup/Model/SystemPackage.php b/setup/src/Magento/Setup/Model/SystemPackage.php index ac076955809..b0e2ed2361c 100755 --- a/setup/src/Magento/Setup/Model/SystemPackage.php +++ b/setup/src/Magento/Setup/Model/SystemPackage.php @@ -55,6 +55,8 @@ class SystemPackage public function getPackageVersions() { $currentCE = '0'; + $currentEE = $currentCE; + $result = []; $systemPackages = []; $systemPackages = $this->getInstalledSystemPackages($systemPackages); @@ -70,6 +72,11 @@ class SystemPackage if ($systemPackageInfo['name'] == 'magento/product-community-edition') { $currentCE = $systemPackageInfo[InfoCommand::CURRENT_VERSION]; } + + if ($systemPackageInfo['name'] == 'magento/product-enterprise-edition') { + $currentEE = $systemPackageInfo[InfoCommand::CURRENT_VERSION]; + } + if (count($versions) > 1) { $versions[0]['name'] .= ' (latest)'; } @@ -84,6 +91,10 @@ class SystemPackage $result = array_merge($this->getAllowedEnterpriseVersions($currentCE), $result); } + if (!in_array('magento/product-b2b-edition', $systemPackages)) { + $result = array_merge($this->getAllowedB2BVersions($currentEE), $result); + } + $result = $this->formatPackages($result); return $result; @@ -116,6 +127,41 @@ class SystemPackage return $result; } + public function getAllowedB2BVersions($currentEE) + { + $result = []; + $b2bVersions = $this->infoCommand->run('magento/product-b2b-edition'); + $b2bVersionsPrepared = []; + $maxVersion = ''; + + if (!is_array($b2bVersions) ) { + return $result; + } + + $b2bVersions['available_versions'] = array_unique( + array_merge( + (array)$b2bVersions['current_version'], + (array)$b2bVersions['available_versions'] + ) + ); + + if ($b2bVersions['available_versions']) { + $b2bVersions = $this->sortVersions($b2bVersions); + if (isset($b2bVersions['available_versions'][0])) { + $maxVersion = $b2bVersions['available_versions'][0]; + } + $b2bVersionsPrepared = $this->filterB2bVersions($currentEE, $b2bVersions, $maxVersion); + } + + if (!empty($b2bVersionsPrepared)) { + $result[] = [ + 'package' => 'magento/product-b2b-edition', + 'versions' => $b2bVersionsPrepared, + ]; + } + return $result; + } + /** * @param array $systemPackageInfo * @param array $versions @@ -128,7 +174,10 @@ class SystemPackage $editionType .= 'CE'; } elseif ($systemPackageInfo['name'] == 'magento/product-enterprise-edition') { $editionType .= 'EE'; + } elseif ($systemPackageInfo['name'] == 'magento/product-b2b-edition') { + $editionType .= 'B2B'; } + foreach ($systemPackageInfo[InfoCommand::NEW_VERSIONS] as $version) { $versions[] = ['id' => $version, 'name' => 'Version ' . $version . ' ' . $editionType, 'current' => false]; } @@ -260,4 +309,28 @@ class SystemPackage } return $eeVersions; } + + public function filterB2bVersions($currentEE, $b2bVersions, $maxVersion) + { + $b2bVersionsPrepared = []; + foreach ($b2bVersions['available_versions'] as $version) { + $requires = $this->composerInfo->getPackageRequirements('magento/product-b2b-edition', $version); + if (array_key_exists('magento/product-enterprise-edition', $requires)) { + /** @var \Composer\Package\Link $eeRequire */ + $eeRequire = $requires['magento/product-enterprise-edition']; + if (version_compare( + $eeRequire->getConstraint()->getPrettyString(), + $currentEE, + '>=' + )) { + $name = 'Version ' . $version . ' B2B'; + if ($maxVersion == $version) { + $name .= ' (latest)'; + } + $b2bVersionsPrepared[] = ['id' => $version, 'name' => $name, 'current' => false]; + } + } + } + return $b2bVersionsPrepared; + } } -- GitLab From 37e54c4cc96cae86ebc44780e73a333ad2e22da1 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 19 Aug 2016 11:30:02 +0300 Subject: [PATCH 526/838] MAGETWO-57176: Notification messages area. Ajax save. --- .../view/adminhtml/web/js/grid/columns/message.js | 6 +++++- .../view/adminhtml/web/js/grid/listing.js | 6 ++++-- .../view/adminhtml/web/template/grid/listing.html | 2 +- .../web/css/source/_module.less | 10 ++++++++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js index 1014ba56340..dc80d136bb4 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js @@ -13,7 +13,11 @@ define([ bodyTmpl: 'Magento_AdminNotification/grid/cells/message', messageIndex: 'text', fieldClass: { - message: true + message: true, + 'message-warning': false, + 'message-progress': false, + 'message-success': false, + 'message-error': false }, statusMap: { 0: 'success', diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js index 716d3334886..1fbda8d0196 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/listing.js @@ -33,8 +33,10 @@ define([ /** @inheritdoc */ showLoader: function () { - this.fixLoaderHeight(); - this._super(); + if (!this.source.firstLoad) { + this.fixLoaderHeight(); + this._super(); + } }, /** diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html index ee9efdfc4cb..80f2f4f2423 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/template/grid/listing.html @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ --> -<div id="system_messages" class="message-system" collapsible> +<div id="system_messages" class="message-system" collapsible visible="totalRecords"> <div class="message-system-inner" outerClick="fixLoaderHeight.bind($data, true)"> <div class="message-system-short"> <button class="message-system-action-dropdown" toggleCollapsible> diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 1d8e98f0a13..5f1f116e966 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -70,7 +70,11 @@ } .message-system-short { - height: @message-system-short-wrapper__height; + min-height: @message-system-short-wrapper__height; + + .action-close { + display: none; + } } .message-system-short-wrapper { @@ -130,10 +134,12 @@ .notices-wrapper { .admin__data-grid-loading-mask { + display: none; z-index: @z-index-5 - 1; + min-height: @message-system-short-wrapper__height + @message-system__border-width; } .admin__data-grid-outer-wrap { - min-height: @message-system-short-wrapper__height + @message-system__border-width; + min-height: 0; } } -- GitLab From cef92b28aa97f2c95415a58cbfe1c8baa9d8ff9a Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Fri, 19 Aug 2016 12:28:18 +0300 Subject: [PATCH 527/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Module/Plugin/DbStatusValidator.php | 65 +++++---- .../Module/Plugin/DbStatusValidatorTest.php | 137 ++++++++++++++++++ 2 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php diff --git a/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php b/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php index 6f312529c12..473c995c130 100644 --- a/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php +++ b/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php @@ -1,22 +1,24 @@ <?php /** - * Validation of DB up to date state - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\Framework\Module\Plugin; -use Magento\Framework\Cache\FrontendInterface; +use Magento\Framework\Cache\FrontendInterface as FrontendCacheInterface; use Magento\Framework\Module\DbVersionInfo; +use Magento\Framework\App\FrontController; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Phrase; +/** + * Validation of DB up to date state + */ class DbStatusValidator { /** - * @var FrontendInterface + * @var FrontendCacheInterface */ private $cache; @@ -26,47 +28,45 @@ class DbStatusValidator private $dbVersionInfo; /** - * @param FrontendInterface $cache + * @param FrontendCacheInterface $cache * @param DbVersionInfo $dbVersionInfo */ - public function __construct( - FrontendInterface $cache, - DbVersionInfo $dbVersionInfo - ) { + public function __construct(FrontendCacheInterface $cache, DbVersionInfo $dbVersionInfo) + { $this->cache = $cache; $this->dbVersionInfo = $dbVersionInfo; } /** - * @param \Magento\Framework\App\FrontController $subject - * @param \Closure $proceed - * @param \Magento\Framework\App\RequestInterface $request + * Perform check if DB is up to date + * + * @param FrontController $subject + * @param RequestInterface $request + * @return void + * @throws LocalizedException * - * @throws \Magento\Framework\Exception\LocalizedException - * @return \Magento\Framework\App\ResponseInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDispatch( - \Magento\Framework\App\FrontController $subject, - \Closure $proceed, - \Magento\Framework\App\RequestInterface $request - ) { + public function beforeDispatch(FrontController $subject, RequestInterface $request) + { if (!$this->cache->load('db_is_up_to_date')) { $errors = $this->dbVersionInfo->getDbVersionErrors(); + if ($errors) { $formattedErrors = $this->formatErrors($errors); - throw new \Magento\Framework\Exception\LocalizedException( - new \Magento\Framework\Phrase( - 'Please upgrade your database: Run "bin/magento setup:upgrade" from the Magento root directory.' - . ' %1The following modules are outdated:%2%3', - [PHP_EOL, PHP_EOL, implode(PHP_EOL, $formattedErrors)] + + throw new LocalizedException( + new Phrase( + 'Please upgrade your database: ' + . "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n" + . "The following modules are outdated:\n%1", + [implode("\n", $formattedErrors)] ) ); } else { $this->cache->save('true', 'db_is_up_to_date'); } } - return $proceed($request); } /** @@ -78,12 +78,13 @@ class DbStatusValidator private function formatErrors($errorsData) { $formattedErrors = []; + foreach ($errorsData as $error) { - $formattedErrors[] = $error[DbVersionInfo::KEY_MODULE] . - ' ' . $error[DbVersionInfo::KEY_TYPE] . - ': current version - ' . $error[DbVersionInfo::KEY_CURRENT ] . - ', required version - ' . $error[DbVersionInfo::KEY_REQUIRED]; + $formattedErrors[] = $error[DbVersionInfo::KEY_MODULE] . ' ' . $error[DbVersionInfo::KEY_TYPE] + . ': current version - ' . $error[DbVersionInfo::KEY_CURRENT] + . ', required version - ' . $error[DbVersionInfo::KEY_REQUIRED]; } + return $formattedErrors; } } diff --git a/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php new file mode 100644 index 00000000000..c17ed886d24 --- /dev/null +++ b/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php @@ -0,0 +1,137 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Test\Unit\Module\Plugin; + +use Magento\Framework\Module\Plugin\DbStatusValidator as DbStatusValidatorPlugin; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Cache\FrontendInterface as FrontendCacheInterface; +use Magento\Framework\Module\DbVersionInfo; +use Magento\Framework\App\FrontController; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\LocalizedException; + +class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var DbStatusValidatorPlugin + */ + private $plugin; + + /** + * @var ObjectManagerHelper + */ + private $objectManagerHelper; + + /** + * @var FrontendCacheInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $cacheMock; + + /** + * @var DbVersionInfo|\PHPUnit_Framework_MockObject_MockObject + */ + private $dbVersionInfoMock; + + /** + * @var FrontController|\PHPUnit_Framework_MockObject_MockObject + */ + private $frontControllerMock; + + /** + * @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; + + protected function setUp() + { + $this->cacheMock = $this->getMockBuilder(FrontendCacheInterface::class) + ->getMockForAbstractClass(); + $this->dbVersionInfoMock = $this->getMockBuilder(DbVersionInfo::class) + ->disableOriginalConstructor() + ->getMock(); + $this->frontControllerMock = $this->getMockBuilder(FrontController::class) + ->disableOriginalConstructor() + ->getMock(); + $this->requestMock = $this->getMockBuilder(RequestInterface::class) + ->getMockForAbstractClass(); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->plugin = $this->objectManagerHelper->getObject( + DbStatusValidatorPlugin::class, + [ + 'cache' => $this->cacheMock, + 'dbVersionInfo' => $this->dbVersionInfoMock + ] + ); + } + + public function testBeforeDispatchUpToDate() + { + $this->cacheMock->expects(static::any()) + ->method('load') + ->with('db_is_up_to_date') + ->willReturn('cache_data'); + $this->dbVersionInfoMock->expects(static::never()) + ->method('getDbVersionErrors'); + $this->cacheMock->expects(static::never()) + ->method('save'); + + $this->plugin->beforeDispatch($this->frontControllerMock, $this->requestMock); + } + + public function testBeforeDispatchOutOfDateNoErrors() + { + $this->cacheMock->expects(static::any()) + ->method('load') + ->with('db_is_up_to_date') + ->willReturn(false); + $this->dbVersionInfoMock->expects(static::once()) + ->method('getDbVersionErrors') + ->willReturn([]); + $this->cacheMock->expects(static::once()) + ->method('save') + ->with('true', 'db_is_up_to_date', [], null) + ->willReturn(true); + + $this->plugin->beforeDispatch($this->frontControllerMock, $this->requestMock); + } + + public function testBeforeDispatchOutOfDateWithErrors() + { + $errors = [ + [ + DbVersionInfo::KEY_MODULE => 'Magento_Module1', + DbVersionInfo::KEY_TYPE => 'schema', + DbVersionInfo::KEY_CURRENT => '3.3.3', + DbVersionInfo::KEY_REQUIRED => '4.4.4' + ], + [ + DbVersionInfo::KEY_MODULE => 'Magento_Module2', + DbVersionInfo::KEY_TYPE => 'data', + DbVersionInfo::KEY_CURRENT => '2.8.7', + DbVersionInfo::KEY_REQUIRED => '5.1.6' + ] + ]; + $message = 'Please upgrade your database: ' + . "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n" + . "The following modules are outdated:\n" + . "Magento_Module1 schema: current version - 3.3.3, required version - 4.4.4\n" + . "Magento_Module2 data: current version - 2.8.7, required version - 5.1.6"; + + $this->cacheMock->expects(static::any()) + ->method('load') + ->with('db_is_up_to_date') + ->willReturn(false); + $this->dbVersionInfoMock->expects(static::once()) + ->method('getDbVersionErrors') + ->willReturn($errors); + $this->cacheMock->expects(static::never()) + ->method('save'); + + $this->setExpectedException(LocalizedException::class, $message); + $this->plugin->beforeDispatch($this->frontControllerMock, $this->requestMock); + } +} \ No newline at end of file -- GitLab From f95de08e36a9326a09a0bb832c6a51b206492de4 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 19 Aug 2016 12:32:06 +0300 Subject: [PATCH 528/838] MAGETWO-57176: Notification messages area. Ajax save. --- .../Magento_AdminNotification/web/css/source/_module.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 5f1f116e966..6dde9aa3bcc 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -135,8 +135,8 @@ .notices-wrapper { .admin__data-grid-loading-mask { display: none; - z-index: @z-index-5 - 1; min-height: @message-system-short-wrapper__height + @message-system__border-width; + z-index: @z-index-5 - 1; } .admin__data-grid-outer-wrap { -- GitLab From 783998efb784158ba748d7246d753ee1d4e68727 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Fri, 19 Aug 2016 13:32:48 +0300 Subject: [PATCH 529/838] MAGETWO-56821: Notification messages area. DataProvider for notification grid --- .../Ui/Component/DataProvider/DataProvider.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php b/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php index 7ab9c5182ce..296fcf5c461 100644 --- a/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php +++ b/app/code/Magento/AdminNotification/Ui/Component/DataProvider/DataProvider.php @@ -13,10 +13,6 @@ use Magento\AdminNotification\Model\ResourceModel\System\Message\Collection\Sync */ class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider { - /** - * @var \Magento\AdminNotification\Model\ResourceModel\System\Message\Collection - */ - protected $collection; /** * DataProvider constructor. * @param string $name -- GitLab From 084157b7031fab6e164bbe56d1c5ef31109cfaef Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov <isentiabov@magento.com> Date: Fri, 19 Aug 2016 15:01:02 +0300 Subject: [PATCH 530/838] MAGETWO-57115: [Github] Braintree Vault payments causing GET order API to throw error #6215 - Replaced token_metadata array by separate fields - Added upgrade data script --- app/code/Magento/Vault/Model/Method/Vault.php | 20 ++++++----- .../Vault/Observer/PaymentTokenAssigner.php | 1 - app/code/Magento/Vault/Setup/UpgradeData.php | 30 ++++++++++++++++- .../Test/Unit/Model/Method/VaultTest.php | 33 ++++++++++++------- .../Observer/PaymentTokenAssignerTest.php | 1 - app/code/Magento/Vault/etc/module.xml | 2 +- 6 files changed, 63 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Vault/Model/Method/Vault.php b/app/code/Magento/Vault/Model/Method/Vault.php index aa0bead2327..0e6689461e1 100644 --- a/app/code/Magento/Vault/Model/Method/Vault.php +++ b/app/code/Magento/Vault/Model/Method/Vault.php @@ -31,6 +31,9 @@ use Magento\Vault\Model\VaultPaymentInterface; */ final class Vault implements VaultPaymentInterface { + /** + * @deprecated + */ const TOKEN_METADATA_KEY = 'token_metadata'; /** @@ -111,6 +114,8 @@ final class Vault implements VaultPaymentInterface * @param PaymentTokenManagementInterface $tokenManagement * @param OrderPaymentExtensionInterfaceFactory $paymentExtensionFactory * @param string $code + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( ConfigInterface $config, @@ -452,17 +457,14 @@ final class Vault implements VaultPaymentInterface private function attachTokenExtensionAttribute(OrderPaymentInterface $orderPayment) { $additionalInformation = $orderPayment->getAdditionalInformation(); - - $tokenData = isset($additionalInformation[self::TOKEN_METADATA_KEY]) - ? $additionalInformation[self::TOKEN_METADATA_KEY] - : null; - - if ($tokenData === null) { - throw new \LogicException("Token metadata should be defined"); + if (empty($additionalInformation[PaymentTokenInterface::CUSTOMER_ID]) || + empty($additionalInformation[PaymentTokenInterface::PUBLIC_HASH]) + ) { + throw new \LogicException('Customer id and public hash should be defined'); } - $customerId = $tokenData[PaymentTokenInterface::CUSTOMER_ID]; - $publicHash = $tokenData[PaymentTokenInterface::PUBLIC_HASH]; + $customerId = $additionalInformation[PaymentTokenInterface::CUSTOMER_ID]; + $publicHash = $additionalInformation[PaymentTokenInterface::PUBLIC_HASH]; $paymentToken = $this->tokenManagement->getByPublicHash($publicHash, $customerId); diff --git a/app/code/Magento/Vault/Observer/PaymentTokenAssigner.php b/app/code/Magento/Vault/Observer/PaymentTokenAssigner.php index 9d5417726d0..7601d49b9fe 100644 --- a/app/code/Magento/Vault/Observer/PaymentTokenAssigner.php +++ b/app/code/Magento/Vault/Observer/PaymentTokenAssigner.php @@ -65,7 +65,6 @@ class PaymentTokenAssigner extends AbstractDataAssignObserver } $paymentModel->setAdditionalInformation( - Vault::TOKEN_METADATA_KEY, [ PaymentTokenInterface::CUSTOMER_ID => $customerId, PaymentTokenInterface::PUBLIC_HASH => $tokenPublicHash diff --git a/app/code/Magento/Vault/Setup/UpgradeData.php b/app/code/Magento/Vault/Setup/UpgradeData.php index 84668ce4443..3925aaa6c94 100644 --- a/app/code/Magento/Vault/Setup/UpgradeData.php +++ b/app/code/Magento/Vault/Setup/UpgradeData.php @@ -22,13 +22,41 @@ class UpgradeData implements UpgradeDataInterface public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $setup->startSetup(); + $connection = $setup->getConnection(); + // data update for Vault module < 2.0.1 if (version_compare($context->getVersion(), '2.0.1', '<')) { - $connection = $setup->getConnection(); + // update sets credit card as default token type $connection->update($setup->getTable(InstallSchema::PAYMENT_TOKEN_TABLE), [ PaymentTokenInterface::TYPE => CreditCardTokenFactory::TOKEN_TYPE_CREDIT_CARD ], PaymentTokenInterface::TYPE . ' = ""'); } + + // data update for Vault module < 2.0.2 + if (version_compare($context->getVersion(), '2.0.2', '<')) { + // update converts additional info with token metadata to single dimensional array + $select = $connection->select() + ->from($setup->getTable('sales_order_payment'), 'entity_id') + ->columns(['additional_information']) + ->where('additional_information LIKE ?', '%token_metadata%'); + + $items = $connection->fetchAll($select); + foreach ($items as $item) { + $additionalInfo = unserialize($item['additional_information']); + $additionalInfo[PaymentTokenInterface::CUSTOMER_ID] = + $additionalInfo['token_metadata'][PaymentTokenInterface::CUSTOMER_ID]; + $additionalInfo[PaymentTokenInterface::PUBLIC_HASH] = + $additionalInfo['token_metadata'][PaymentTokenInterface::PUBLIC_HASH]; + unset($additionalInfo['token_metadata']); + + $connection->update( + $setup->getTable('sales_order_payment'), + ['additional_information' => serialize($additionalInfo)], + ['entity_id = ?' => $item['entity_id']] + ); + } + } + $setup->endSetup(); } } diff --git a/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php b/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php index 32e783278e1..fc6f3e4d239 100644 --- a/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php +++ b/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php @@ -50,10 +50,12 @@ class VaultTest extends \PHPUnit_Framework_TestCase } /** + * @param array $additionalInfo * @expectedException \LogicException - * @expectedExceptionMessage Token metadata should be defined + * @expectedExceptionMessage Customer id and public hash should be defined + * @dataProvider additionalInfoDataProvider */ - public function testAuthorizeNoTokenMetadata() + public function testAuthorizeNoTokenMetadata(array $additionalInfo) { $paymentModel = $this->getMockBuilder(Payment::class) ->disableOriginalConstructor() @@ -61,13 +63,26 @@ class VaultTest extends \PHPUnit_Framework_TestCase $paymentModel->expects(static::once()) ->method('getAdditionalInformation') - ->willReturn([]); + ->willReturn($additionalInfo); /** @var Vault $model */ $model = $this->objectManager->getObject(Vault::class); $model->authorize($paymentModel, 0); } + /** + * Get list of additional information variations + * @return array + */ + public function additionalInfoDataProvider() + { + return [ + ['additionalInfo' => []], + ['additionalInfo' => ['customer_id' => 1]], + ['additionalInfo' => ['public_hash' => 'df768aak12uf']], + ]; + } + /** * @expectedException \LogicException * @expectedExceptionMessage No token found @@ -86,10 +101,8 @@ class VaultTest extends \PHPUnit_Framework_TestCase ->method('getAdditionalInformation') ->willReturn( [ - Vault::TOKEN_METADATA_KEY => [ - PaymentTokenInterface::CUSTOMER_ID => $customerId, - PaymentTokenInterface::PUBLIC_HASH => $publicHash - ] + PaymentTokenInterface::CUSTOMER_ID => $customerId, + PaymentTokenInterface::PUBLIC_HASH => $publicHash ] ); $tokenManagement->expects(static::once()) @@ -133,10 +146,8 @@ class VaultTest extends \PHPUnit_Framework_TestCase ->method('getAdditionalInformation') ->willReturn( [ - Vault::TOKEN_METADATA_KEY => [ - PaymentTokenInterface::CUSTOMER_ID => $customerId, - PaymentTokenInterface::PUBLIC_HASH => $publicHash - ] + PaymentTokenInterface::CUSTOMER_ID => $customerId, + PaymentTokenInterface::PUBLIC_HASH => $publicHash ] ); $tokenManagement->expects(static::once()) diff --git a/app/code/Magento/Vault/Test/Unit/Observer/PaymentTokenAssignerTest.php b/app/code/Magento/Vault/Test/Unit/Observer/PaymentTokenAssignerTest.php index 6856cde3ebd..d973e1cce57 100644 --- a/app/code/Magento/Vault/Test/Unit/Observer/PaymentTokenAssignerTest.php +++ b/app/code/Magento/Vault/Test/Unit/Observer/PaymentTokenAssignerTest.php @@ -161,7 +161,6 @@ class PaymentTokenAssignerTest extends \PHPUnit_Framework_TestCase $paymentModel->expects(static::once()) ->method('setAdditionalInformation') ->with( - Vault::TOKEN_METADATA_KEY, [ PaymentTokenInterface::CUSTOMER_ID => $customerId, PaymentTokenInterface::PUBLIC_HASH => $publicHash diff --git a/app/code/Magento/Vault/etc/module.xml b/app/code/Magento/Vault/etc/module.xml index 740d93b4e13..7ab8db1d86f 100644 --- a/app/code/Magento/Vault/etc/module.xml +++ b/app/code/Magento/Vault/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Vault" setup_version="2.0.1"> + <module name="Magento_Vault" setup_version="2.0.2"> <sequence> <module name="Magento_Sales"/> <module name="Magento_Store"/> -- GitLab From f7bf43cc429f42148f3c1d3959f087a133fd417a Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Fri, 19 Aug 2016 15:26:53 +0300 Subject: [PATCH 531/838] MAGETWO-54134: CE module depends on EE code - Removed redundant dependencies --- app/code/Magento/Usps/Model/Carrier.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 3040d18ad80..12345f5ab1f 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -21,17 +21,19 @@ use Magento\Framework\Xml\Security; */ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\Carrier\CarrierInterface { - /** - * USPS containers - */ + /** @deprecated */ const CONTAINER_VARIABLE = 'VARIABLE'; + /** @deprecated */ const CONTAINER_FLAT_RATE_BOX = 'FLAT RATE BOX'; + /** @deprecated */ const CONTAINER_FLAT_RATE_ENVELOPE = 'FLAT RATE ENVELOPE'; + /** @deprecated */ const CONTAINER_RECTANGULAR = 'RECTANGULAR'; + /** @deprecated */ const CONTAINER_NONRECTANGULAR = 'NONRECTANGULAR'; /** -- GitLab From b20f917f1328d8eafa7986e60868a3c1463b2721 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Fri, 19 Aug 2016 15:46:31 +0300 Subject: [PATCH 532/838] MAGETWO-54176: Wrong quantity validation for bundle option lines --- .../Ui/DataProvider/Product/Form/Modifier/BundlePanel.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index b0ac4069141..f4df2038b4e 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -642,7 +642,8 @@ class BundlePanel extends AbstractModifier 'sortOrder' => 100, 'validation' => [ 'required-entry' => true, - 'validate-zero-or-greater' => true + 'validate-number' => true, + 'validate-greater-than-zero' => true ], 'imports' => [ 'isInteger' => '${ $.provider }:${ $.parentScope }.selection_qty_is_integer' -- GitLab From 515a4954f7a094e5e0e41c55137ac0aee415bf74 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Fri, 19 Aug 2016 16:00:32 +0300 Subject: [PATCH 533/838] MAGETWO-56703: Around plugins refactoring: stabilize code --- .../Test/Unit/Model/Url/Plugin/SignatureTest.php | 10 ++++++++-- .../Framework/Module/Plugin/DbStatusValidator.php | 13 ++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php b/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php index 31dd9af4771..a55ea73aefc 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php @@ -29,7 +29,11 @@ class SignatureTest extends \PHPUnit_Framework_TestCase { $this->config = $this->getMock(\Magento\Framework\View\Url\ConfigInterface::class); $this->deploymentVersion = $this->getMock( - \Magento\Framework\App\View\Deployment\Version::class, [], [], '', false + \Magento\Framework\App\View\Deployment\Version::class, + [], + [], + '', + false ); $this->object = new Signature($this->config, $this->deploymentVersion); } @@ -72,7 +76,9 @@ class SignatureTest extends \PHPUnit_Framework_TestCase $url = $this->getMockForAbstractClass(\Magento\Framework\Url\ScopeInterface::class); $actualResult = $this->object->afterGetBaseUrl( - $url, 'http://127.0.0.1/magento/pub/static/', \Magento\Framework\UrlInterface::URL_TYPE_STATIC + $url, + 'http://127.0.0.1/magento/pub/static/', + \Magento\Framework\UrlInterface::URL_TYPE_STATIC ); $this->assertEquals('http://127.0.0.1/magento/pub/static/version123/', $actualResult); } diff --git a/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php b/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php index 473c995c130..850d64b14ae 100644 --- a/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php +++ b/lib/internal/Magento/Framework/Module/Plugin/DbStatusValidator.php @@ -53,16 +53,11 @@ class DbStatusValidator $errors = $this->dbVersionInfo->getDbVersionErrors(); if ($errors) { - $formattedErrors = $this->formatErrors($errors); + $message = 'Please upgrade your database: ' + . "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n" + . "The following modules are outdated:\n%1"; - throw new LocalizedException( - new Phrase( - 'Please upgrade your database: ' - . "Run \"bin/magento setup:upgrade\" from the Magento root directory.\n" - . "The following modules are outdated:\n%1", - [implode("\n", $formattedErrors)] - ) - ); + throw new LocalizedException(new Phrase($message, [implode("\n", $this->formatErrors($errors))])); } else { $this->cache->save('true', 'db_is_up_to_date'); } -- GitLab From 65cb8dd0860cd4c8a980aac4d0555b4deea59fb5 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Fri, 19 Aug 2016 16:07:31 +0300 Subject: [PATCH 534/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php b/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php index 3d48ee060f3..23b7fa31fb5 100644 --- a/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php +++ b/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php @@ -19,7 +19,7 @@ class SwitcherPlugin * @param StoreSwitcherBlock $subject * @param string $route * @param array $params - * @return string + * @return array */ public function beforeGetUrl(StoreSwitcherBlock $subject, $route = '', $params = []) { -- GitLab From 2a088fe4f06748cd301b66a15b625d45e84fd71b Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 19 Aug 2016 16:11:32 +0300 Subject: [PATCH 535/838] MAGETWO-57176: Notification messages area. Ajax save. --- app/code/Magento/Ui/view/base/web/js/form/form.js | 7 ++++--- .../Ui/view/base/web/js/lib/validation/validator.js | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js index 672af8a7ed8..f1f45c419d0 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/form.js @@ -248,15 +248,16 @@ define([ * @param {Object} data */ save: function (redirect, data) { - var scrollTop; + var scrollTop, + $errorElem = $(this.errorClass); this.validate(); if (!this.additionalInvalid && !this.source.get('params.invalid')) { this.setAdditionalData(data) .submit(redirect); - } else { - scrollTop = $(this.errorClass).offset().top - window.innerHeight / 2; + } else if ($errorElem.length) { + scrollTop = $errorElem.offset().top - window.innerHeight / 2; window.scrollTo(0, scrollTop); } }, diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/validator.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/validator.js index 764b11dfbfe..7823871fd69 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/validation/validator.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/validator.js @@ -27,12 +27,16 @@ define([ message: '' }; + if (_.isObject(params)) { + message = params.message || ''; + } + if (!rulesList[id]) { return result; } rule = rulesList[id]; - message = rule.message; + message = message || rule.message; valid = rule.handler(value, params, additionalParams); if (!valid) { @@ -68,7 +72,7 @@ define([ }; _.every(rules, function (ruleParams, id) { - if (ruleParams !== false || additionalParams) { + if (ruleParams.validate || ruleParams !== false || additionalParams) { result = validate(id, value, ruleParams, additionalParams); return result.passed; -- GitLab From ae2ce780d98018f3a4a93ad046298c1d3a751631 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Fri, 19 Aug 2016 16:13:22 +0300 Subject: [PATCH 536/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php | 1 + .../Test/Unit/Model/Method/Checks/SpecificationPluginTest.php | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php index 13cc51a7dc4..48314c28ceb 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/Structure/Element/FieldPluginTest.php @@ -67,6 +67,7 @@ class FieldPluginTest extends \PHPUnit_Framework_TestCase /** * @param string $subjectPath * @param string $expectedConfigPath + * * @dataProvider afterGetConfigPathDataProvider */ public function testAroundGetConfigPath($subjectPath, $expectedConfigPath) diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php index fcab94d2d22..0994088d84a 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Method/Checks/SpecificationPluginTest.php @@ -130,6 +130,7 @@ class SpecificationPluginTest extends \PHPUnit_Framework_TestCase /** * @param int $count + * * @dataProvider afterIsApplicableDataProvider */ public function testAfterIsApplicable($count) -- GitLab From 1944bf08cc03fa93cc604e4196f7bca3ff697547 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <okolesnyk@magento.com> Date: Fri, 19 Aug 2016 16:39:42 +0300 Subject: [PATCH 537/838] MTA-3464: Merge Domain Functional Bamboo Plan - Fix issues found by static tests --- .../UpdateCustomerBackendEntityTest.php | 34 +++++++++++++++---- .../ViewedProductsReportEntityTest.php | 7 +++- .../OnePageCheckoutWithDiscountTest.php | 2 +- .../TestCase/DeleteSavedCreditCardTest.php | 32 +++++++++++++---- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php index 4baa9985742..d6820720d89 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php @@ -100,23 +100,45 @@ class UpdateCustomerBackendEntityTest extends Injectable : $initialCustomer->getData(); $groupId = $customer->hasData('group_id') ? $customer : $initialCustomer; $data['group_id'] = ['customerGroup' => $groupId->getDataFieldConfig('group_id')['source']->getCustomerGroup()]; + $customerAddress = $this->prepareCustomerAddress($initialCustomer, $address, $addressToDelete); + if (!empty($customerAddress)) { + $data['address'] = $customerAddress; + } + + return $this->fixtureFactory->createByCode( + 'customer', + ['data' => $data] + ); + } + + /** + * Prepare address for customer entity. + * + * @param Customer $initialCustomer + * @param Address|null $address + * @param Address|null $addressToDelete + * @return array + */ + private function prepareCustomerAddress( + Customer $initialCustomer, + Address $address = null, + Address $addressToDelete = null + ) { + $customerAddress = []; if ($initialCustomer->hasData('address')) { $addressesList = $initialCustomer->getDataFieldConfig('address')['source']->getAddresses(); foreach ($addressesList as $key => $addressFixture) { if ($addressToDelete === null || $addressFixture != $address) { - $data['address'] = ['addresses' => [$key => $addressFixture]]; + $customerAddress = ['addresses' => [$key => $addressFixture]]; } } } if ($address !== null) { - $data['address']['addresses'][] = $address; + $customerAddress['addresses'][] = $address; } - return $this->fixtureFactory->createByCode( - 'customer', - ['data' => $data] - ); + return $customerAddress; } /** diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php index 4e410e38d10..905fa8fb70f 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/ViewedProductsReportEntityTest.php @@ -62,6 +62,7 @@ class ViewedProductsReportEntityTest extends Injectable * @var CatalogProductIndex */ protected $catalogProductIndexPage; + /** * Catalog product index page * @@ -149,7 +150,11 @@ class ViewedProductsReportEntityTest extends Injectable foreach ($products as $key => $product) { for ($i = 0; $i < $total[$key]; $i++) { $this->browser->open($_ENV['app_frontend_url'] . $product->getUrlKey() . '.html'); - $this->assertEquals($product->getName(), $this->cmsIndex->getTitleBlock()->getTitle(), 'Could not open product page'); + $this->assertEquals( + $product->getName(), + $this->cmsIndex->getTitleBlock()->getTitle(), + 'Could not open product page.' + ); } } } diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php index 9a8e2b75231..95fae4642d8 100644 --- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php +++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/TestCase/OnePageCheckoutWithDiscountTest.php @@ -24,4 +24,4 @@ class OnePageCheckoutWithDiscountTest extends Scenario { $this->executeScenario(); } -} \ No newline at end of file +} diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php index 3f3be6eb71d..a90bd37f330 100644 --- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php +++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php @@ -25,6 +25,7 @@ use Magento\Vault\Test\Constraint\AssertCreditCardNotPresentOnCheckout; * * @group Vault * @ZephyrId MAGETWO-54059, MAGETWO-54072, MAGETWO-54068, MAGETWO-54015, MAGETWO-54011 + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DeleteSavedCreditCardTest extends Injectable { @@ -33,11 +34,28 @@ class DeleteSavedCreditCardTest extends Injectable const TEST_TYPE = '3rd_party_test'; /* end tags */ + /** + * Page for one page checkout. + * + * @var CheckoutOnepage + */ + private $checkoutOnepage; + + /** + * Injection data. + * + * @param CheckoutOnepage $checkoutOnepage + * @return void + */ + public function __inject(CheckoutOnepage $checkoutOnepage) + { + $this->checkoutOnepage = $checkoutOnepage; + } + /** * Runs delete saved credit card test. * * @param AssertCreditCardNotPresentOnCheckout $assertCreditCardNotPresentOnCheckout - * @param CheckoutOnepage $checkoutOnepage * @param $products * @param $configData * @param $customer @@ -46,10 +64,10 @@ class DeleteSavedCreditCardTest extends Injectable * @param $shipping * @param array $payments * @param $creditCardSave + * @return void */ public function test( AssertCreditCardNotPresentOnCheckout $assertCreditCardNotPresentOnCheckout, - CheckoutOnepage $checkoutOnepage, $products, $configData, $customer, @@ -68,7 +86,7 @@ class DeleteSavedCreditCardTest extends Injectable foreach ($payments as $key => $payment) { $this->addToCart($products); $this->proceedToCheckout(); - if($key < 1) { // if this is the first order to be placed + if ($key < 1) { // if this is the first order to be placed $this->selectCheckoutMethod($checkoutMethod, $customer); $this->fillShippingAddress($shippingAddress); } @@ -83,7 +101,7 @@ class DeleteSavedCreditCardTest extends Injectable } // Delete credit cards from Stored Payment Methods and verify they are not available on checkout $paymentsCount = count($payments); - for($i = 2; $i < $paymentsCount; $i++) { + for ($i = 2; $i < $paymentsCount; $i++) { $deletedCard = $this->deleteCreditCardFromMyAccount( $customer, $payments[$i]['creditCard'], @@ -93,7 +111,7 @@ class DeleteSavedCreditCardTest extends Injectable $this->proceedToCheckout(); $this->fillShippingMethod($shipping); $assertCreditCardNotPresentOnCheckout->processAssert( - $checkoutOnepage, + $this->checkoutOnepage, $deletedCard['deletedCreditCard'] ); } @@ -243,7 +261,7 @@ class DeleteSavedCreditCardTest extends Injectable ); $saveCreditCardStep->run(); } - + /** * @return void */ @@ -254,7 +272,7 @@ class DeleteSavedCreditCardTest extends Injectable ); $fillBillingInformationStep->run(); } - + /** * @return void */ -- GitLab From 7cc1727de7f019833f444bdd9e631645a5da27f2 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Fri, 19 Aug 2016 17:16:18 +0300 Subject: [PATCH 538/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Paypal/Model/Config/StructurePlugin.php | 59 +++++++------------ .../Unit/Model/Config/StructurePluginTest.php | 48 +++++++-------- 2 files changed, 46 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/Paypal/Model/Config/StructurePlugin.php b/app/code/Magento/Paypal/Model/Config/StructurePlugin.php index 3d3f637e542..f45a7948906 100644 --- a/app/code/Magento/Paypal/Model/Config/StructurePlugin.php +++ b/app/code/Magento/Paypal/Model/Config/StructurePlugin.php @@ -24,22 +24,17 @@ class StructurePlugin /** * @var BackendHelper */ - protected $_helper; + private $backendHelper; /** * @var ScopeDefiner */ - protected $_scopeDefiner; - - /** - * @var bool - */ - private $isSectionChanged; + private $scopeDefiner; /** * @var string[] */ - private static $_paypalConfigCountries = [ + private static $paypalConfigCountries = [ 'payment_us', 'payment_ca', 'payment_au', @@ -57,12 +52,10 @@ class StructurePlugin * @param ScopeDefiner $scopeDefiner * @param BackendHelper $helper */ - public function __construct( - ScopeDefiner $scopeDefiner, - BackendHelper $helper - ) { - $this->_scopeDefiner = $scopeDefiner; - $this->_helper = $helper; + public function __construct(ScopeDefiner $scopeDefiner, BackendHelper $helper) + { + $this->scopeDefiner = $scopeDefiner; + $this->backendHelper = $helper; } /** @@ -73,10 +66,12 @@ class StructurePlugin */ public static function getPaypalConfigCountries($addOther = false) { - $countries = self::$_paypalConfigCountries; + $countries = self::$paypalConfigCountries; + if ($addOther) { $countries[] = 'payment_other'; } + return $countries; } @@ -84,17 +79,18 @@ class StructurePlugin * Substitute payment section with PayPal configs * * @param Structure $subject + * @param \Closure $proceed * @param array $pathParts - * @return array + * @return ElementInterface|null * * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function beforeGetElementByPathParts(Structure $subject, array $pathParts) + public function aroundGetElementByPathParts(Structure $subject, \Closure $proceed, array $pathParts) { - $this->isSectionChanged = $pathParts[0] == 'payment'; + $isSectionChanged = $pathParts[0] == 'payment'; - if ($this->isSectionChanged) { - $requestedCountrySection = 'payment_' . strtolower($this->_helper->getConfigurationCountryCode()); + if ($isSectionChanged) { + $requestedCountrySection = 'payment_' . strtolower($this->backendHelper->getConfigurationCountryCode()); if (in_array($requestedCountrySection, self::getPaypalConfigCountries())) { $pathParts[0] = $requestedCountrySection; @@ -103,21 +99,9 @@ class StructurePlugin } } - return [$pathParts]; - } + $result = $proceed($pathParts); - /** - * Substitute payment section with PayPal configs - * - * @param Structure $subject - * @param ElementInterface|null $result - * @return ElementInterface|null - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function afterGetElementByPathParts(Structure $subject, ElementInterface $result = null) - { - if ($this->isSectionChanged && $result) { + if ($isSectionChanged && $result) { if ($result instanceof Section) { $this->restructurePayments($result); $result->setData( @@ -125,7 +109,7 @@ class StructurePlugin $result->getData(), ['showInDefault' => true, 'showInWebsite' => true, 'showInStore' => true] ), - $this->_scopeDefiner->getScope() + $this->scopeDefiner->getScope() ); } } @@ -134,7 +118,8 @@ class StructurePlugin } /** - * Changes payment config structure. + * Change payment config structure + * * Groups which have `displayIn` element, transfer to appropriate group. * Groups without `displayIn` transfer to other payment methods group. * @@ -163,7 +148,7 @@ class StructurePlugin } $configuration['children'] = $sectionMap; - $result->setData($configuration, $this->_scopeDefiner->getScope()); + $result->setData($configuration, $this->scopeDefiner->getScope()); } /** diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php index 0139566cbf6..3b639bca2c8 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php @@ -85,26 +85,25 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase * @param array $pathParts * @param bool $returnResult * - * @dataProvider beforeAndAfterGetElementByPathPartsNonPaymentDataProvider + * @dataProvider aroundGetElementByPathPartsNonPaymentDataProvider */ - public function testBeforeAndAfterGetElementByPathPartsNonPayment($pathParts, $returnResult) + public function testAroundGetElementByPathPartsNonPayment($pathParts, $returnResult) { $result = $returnResult ? $this->elementConfigStructureMock : null; + $proceed = function () use ($result) { + return $result; + }; - $this->assertEquals( - [$pathParts], - $this->plugin->beforeGetElementByPathParts($this->configStructureMock, $pathParts) - ); $this->assertSame( $result, - $this->plugin->afterGetElementByPathParts($this->configStructureMock, $result) + $this->plugin->aroundGetElementByPathParts($this->configStructureMock, $proceed, $pathParts) ); } /** * @return array */ - public function beforeAndAfterGetElementByPathPartsNonPaymentDataProvider() + public function aroundGetElementByPathPartsNonPaymentDataProvider() { return [ [['non-payment', 'group1', 'group2', 'field'], true], @@ -119,21 +118,21 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase * @param string $countryCode * @param array $expectedPathParts * - * @dataProvider beforeAndAfterGetElementByPathPartsDataProvider + * @dataProvider aroundGetElementByPathPartsDataProvider */ - public function testBeforeAndAfterGetElementByPathPartsNoResult($pathParts, $countryCode, $expectedPathParts) + public function testAroundGetElementByPathPartsNoResult($pathParts, $countryCode, $expectedPathParts) { + $proceed = function () { + return null; + }; + $this->backendHelperMock->expects(static::once()) ->method('getConfigurationCountryCode') ->willReturn($countryCode); - $this->assertEquals( - [$expectedPathParts], - $this->plugin->beforeGetElementByPathParts($this->configStructureMock, $pathParts) - ); $this->assertEquals( null, - $this->plugin->afterGetElementByPathParts($this->configStructureMock, null) + $this->plugin->aroundGetElementByPathParts($this->configStructureMock, $proceed, $pathParts) ); } @@ -142,28 +141,29 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase * @param string $countryCode * @param array $expectedPathParts * - * @dataProvider beforeAndAfterGetElementByPathPartsDataProvider + * @dataProvider aroundGetElementByPathPartsDataProvider */ - public function testBeforeAndAfterGetElementByPathParts($pathParts, $countryCode, $expectedPathParts) + public function testAroundGetElementByPathParts($pathParts, $countryCode, $expectedPathParts) { + $result = $this->elementConfigStructureMock; + $proceed = function () use ($result) { + return $result; + }; + $this->backendHelperMock->expects(static::once()) ->method('getConfigurationCountryCode') ->willReturn($countryCode); - $this->assertEquals( - [$expectedPathParts], - $this->plugin->beforeGetElementByPathParts($this->configStructureMock, $pathParts) - ); $this->assertSame( $this->elementConfigStructureMock, - $this->plugin->afterGetElementByPathParts($this->configStructureMock, $this->elementConfigStructureMock) + $this->plugin->aroundGetElementByPathParts($this->configStructureMock, $proceed, $pathParts) ); } /** * @return array */ - public function beforeAndAfterGetElementByPathPartsDataProvider() + public function aroundGetElementByPathPartsDataProvider() { return [ [ @@ -175,7 +175,7 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase ['payment', 'group1', 'group2', 'field'], 'DE', ['payment_de', 'group1', 'group2', 'field'] - ], + ] ]; } } -- GitLab From 56e9c862965b85d6187bf45a39472e5da2e37b0a Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 19 Aug 2016 17:18:48 +0300 Subject: [PATCH 539/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage - Removed http request from constructor; --- .../Store/App/Action/Plugin/Context.php | 10 +-------- .../Unit/App/Action/Plugin/ContextTest.php | 21 ++++--------------- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Store/App/Action/Plugin/Context.php b/app/code/Magento/Store/App/Action/Plugin/Context.php index 267d7cd5c22..2ad390316b3 100644 --- a/app/code/Magento/Store/App/Action/Plugin/Context.php +++ b/app/code/Magento/Store/App/Action/Plugin/Context.php @@ -29,11 +29,6 @@ class Context */ protected $httpContext; - /** - * @var \Magento\Framework\App\Request\Http - */ - protected $httpRequest; - /** * @var \Magento\Store\Model\StoreManagerInterface */ @@ -47,20 +42,17 @@ class Context /** * @param \Magento\Framework\Session\SessionManagerInterface $session * @param \Magento\Framework\App\Http\Context $httpContext - * @param \Magento\Framework\App\Request\Http $httpRequest * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param StoreCookieManagerInterface $storeCookieManager */ public function __construct( \Magento\Framework\Session\SessionManagerInterface $session, \Magento\Framework\App\Http\Context $httpContext, - \Magento\Framework\App\Request\Http $httpRequest, \Magento\Store\Model\StoreManagerInterface $storeManager, StoreCookieManagerInterface $storeCookieManager ) { $this->session = $session; $this->httpContext = $httpContext; - $this->httpRequest = $httpRequest; $this->storeManager = $storeManager; $this->storeCookieManager = $storeCookieManager; } @@ -76,7 +68,7 @@ class Context /** @var \Magento\Store\Model\Store $defaultStore */ $defaultStore = $this->storeManager->getWebsite()->getDefaultStore(); - $storeCode = $this->httpRequest->getParam( + $storeCode = $request->getParam( StoreResolverInterface::PARAM_NAME, $this->storeCookieManager->getStoreCodeFromCookie() ); diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php index 1fd9bb5fe63..2dd233182e5 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php @@ -37,11 +37,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase */ protected $httpContextMock; - /** - * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject - */ - protected $httpRequestMock; - /** * @var \Magento\Store\Model\StoreManager|\PHPUnit_Framework_MockObject_MockObject */ @@ -96,13 +91,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase '', false ); - $this->httpRequestMock = $this->getMock( - \Magento\Framework\App\Request\Http::class, - ['getParam'], - [], - '', - false - ); $this->storeManager = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); $this->storeCookieManager = $this->getMock(\Magento\Store\Api\StoreCookieManagerInterface::class); $this->storeMock = $this->getMock( @@ -136,7 +124,6 @@ class ContextTest extends \PHPUnit_Framework_TestCase [ 'session' => $this->sessionMock, 'httpContext' => $this->httpContextMock, - 'httpRequest' => $this->httpRequestMock, 'storeManager' => $this->storeManager, 'storeCookieManager' => $this->storeCookieManager, ] @@ -172,7 +159,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('getCode') ->willReturn('custom_store'); - $this->httpRequestMock->expects($this->once()) + $this->requestMock->expects($this->once()) ->method('getParam') ->with($this->equalTo('___store')) ->will($this->returnValue('default')); @@ -209,7 +196,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->method('getCode') ->willReturn('custom_store'); - $this->httpRequestMock->expects($this->once()) + $this->requestMock->expects($this->once()) ->method('getParam') ->with($this->equalTo('___store')) ->will($this->returnValue('default')); @@ -248,7 +235,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ] ]; - $this->httpRequestMock->expects($this->once()) + $this->requestMock->expects($this->once()) ->method('getParam') ->with($this->equalTo('___store')) ->will($this->returnValue($store)); @@ -292,7 +279,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ] ]; - $this->httpRequestMock->expects($this->once()) + $this->requestMock->expects($this->once()) ->method('getParam') ->with($this->equalTo('___store')) ->will($this->returnValue($store)); -- GitLab From 2be28ba1d1eed588023fc0d07bfb7a59ec76d519 Mon Sep 17 00:00:00 2001 From: Yuri Kovsher <ikovsher@magento.com> Date: Fri, 19 Aug 2016 17:39:18 +0300 Subject: [PATCH 540/838] MAGETWO-56703: Around plugins refactoring: stabilize code --- .../Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php b/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php index c17ed886d24..f22192639f7 100644 --- a/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/Module/Plugin/DbStatusValidatorTest.php @@ -134,4 +134,4 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase $this->setExpectedException(LocalizedException::class, $message); $this->plugin->beforeDispatch($this->frontControllerMock, $this->requestMock); } -} \ No newline at end of file +} -- GitLab From 89ee3f9fb74c1704ebe50bf29102bc27dd4b293c Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Fri, 19 Aug 2016 18:10:23 +0300 Subject: [PATCH 541/838] MAGETWO-54134: CE module depends on EE code - Removed plugin --- .../Model/Carrier/AbstractCarrierOnline.php | 3 +- app/code/Magento/Usps/Model/Carrier.php | 28 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php index af310da3064..296a3302de7 100644 --- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php +++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php @@ -596,11 +596,12 @@ abstract class AbstractCarrierOnline extends AbstractCarrier * Check whether girth is allowed for the carrier * * @param null|string $countyDest + * @param null|string $carrierMethodCode * @return bool * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @api */ - public function isGirthAllowed($countyDest = null) + public function isGirthAllowed($countyDest = null, $carrierMethodCode = null) { return false; } diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 12345f5ab1f..d12341659cb 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -8,11 +8,13 @@ namespace Magento\Usps\Model; +use Magento\Framework\App\ObjectManager; use Magento\Quote\Model\Quote\Address\RateRequest; use Magento\Shipping\Helper\Carrier as CarrierHelper; use Magento\Shipping\Model\Carrier\AbstractCarrierOnline; use Magento\Shipping\Model\Rate\Result; use Magento\Framework\Xml\Security; +use Magento\Usps\Helper\Data as DataHelper; /** * USPS shipping @@ -128,6 +130,11 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C 'USERID' ]; + /** + * @var DataHelper + */ + private $dataHelper; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory @@ -1982,11 +1989,13 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C * Check whether girth is allowed for the USPS * * @param null|string $countyDest + * @param null|string $carrierMethodCode * @return bool */ - public function isGirthAllowed($countyDest = null) + public function isGirthAllowed($countyDest = null, $carrierMethodCode = null) { - return $this->_isUSCountry($countyDest) ? false : true; + return $this->_isUSCountry($countyDest) + && $this->getDataHelper()->displayGirthValue($carrierMethodCode) ? false : true; } /** @@ -2091,4 +2100,19 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C return $data; } + + /** + * Gets Data helper object + * + * @return DataHelper + * @deprecated + */ + private function getDataHelper() + { + if (!$this->dataHelper) { + $this->dataHelper = ObjectManager::getInstance()->get(DataHelper::class); + } + + return $this->dataHelper; + } } -- GitLab From 65abe1db7180be75350349cbb64c3c205cfba46a Mon Sep 17 00:00:00 2001 From: Vladyslav Shcherbyna <vshcherbyna@magento.com> Date: Fri, 19 Aug 2016 18:19:04 +0300 Subject: [PATCH 542/838] MAGETWO-54677: Order status change after Shipment creation through API --- .../Shipment/Validation/QuantityValidatorTest.php | 10 ++++++++-- .../Controller/Adminhtml/Order/Shipment/Save.php | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php index 3d59b1d2936..01cccd24586 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Shipment/Validation/QuantityValidatorTest.php @@ -45,7 +45,10 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->shipmentMock->expects($this->once()) ->method('getOrderId') ->willReturn(null); - $this->assertEquals([__('Order Id is required for shipment document')], $this->validator->validate($this->shipmentMock)); + $this->assertEquals( + [__('Order Id is required for shipment document')], + $this->validator->validate($this->shipmentMock) + ); } public function testValidateTrackWithoutItems() @@ -56,6 +59,9 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->shipmentMock->expects($this->once()) ->method('getItems') ->willReturn(null); - $this->assertEquals([__('You can\'t create a shipment without products.')], $this->validator->validate($this->shipmentMock)); + $this->assertEquals( + [__('You can\'t create a shipment without products.')], + $this->validator->validate($this->shipmentMock) + ); } } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php index a615ffa5c3a..d265159bc63 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php @@ -7,7 +7,6 @@ namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment; use Magento\Backend\App\Action; -use Magento\Framework\App\ObjectManager; use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator; /** @@ -193,7 +192,7 @@ class Save extends \Magento\Backend\App\Action private function getShipmentValidator() { if ($this->shipmentValidator === null) { - $this->shipmentValidator = ObjectManager::getInstance()->get( + $this->shipmentValidator = $this->_objectManager->get( \Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface::class ); } -- GitLab From 11706dba56f8ab74798093ded70692b5dcb7636c Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 19 Aug 2016 18:23:59 +0300 Subject: [PATCH 543/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- setup/pub/magento/setup/select-version.js | 11 +++- .../src/Magento/Setup/Model/SystemPackage.php | 57 +++++++++++++------ 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/setup/pub/magento/setup/select-version.js b/setup/pub/magento/setup/select-version.js index cd01b9ee861..6a6ecdd9a99 100644 --- a/setup/pub/magento/setup/select-version.js +++ b/setup/pub/magento/setup/select-version.js @@ -29,8 +29,15 @@ angular.module('select-version', ['ngStorage']) $http.get('index.php/select-version/systemPackage', {'responseType' : 'json'}) .success(function (data) { if (data.responseType != 'error') { - if (data.packages.length == 1) { - $scope.upgradeProcessError = true; + $scope.upgradeProcessError = true; + + angular.forEach(data.packages, function (value, key) { + if (!value.current) { + return $scope.upgradeProcessError = false; + } + }); + + if ($scope.upgradeProcessError) { $scope.upgradeProcessErrorMessage = "You're already using the latest version, there's nothing for us to do."; } else { $scope.selectedOption = []; diff --git a/setup/src/Magento/Setup/Model/SystemPackage.php b/setup/src/Magento/Setup/Model/SystemPackage.php index b0e2ed2361c..38249555380 100755 --- a/setup/src/Magento/Setup/Model/SystemPackage.php +++ b/setup/src/Magento/Setup/Model/SystemPackage.php @@ -61,13 +61,12 @@ class SystemPackage $systemPackages = []; $systemPackages = $this->getInstalledSystemPackages($systemPackages); foreach ($systemPackages as $systemPackage) { - $versions = []; $systemPackageInfo = $this->infoCommand->run($systemPackage); if (!$systemPackageInfo) { throw new \RuntimeException("We cannot retrieve information on $systemPackage."); } - $versions = $this->getSystemPackageVersions($systemPackageInfo, $versions); + $versions = $this->getSystemPackageVersions($systemPackageInfo); if ($systemPackageInfo['name'] == 'magento/product-community-edition') { $currentCE = $systemPackageInfo[InfoCommand::CURRENT_VERSION]; @@ -91,7 +90,10 @@ class SystemPackage $result = array_merge($this->getAllowedEnterpriseVersions($currentCE), $result); } - if (!in_array('magento/product-b2b-edition', $systemPackages)) { + if ( + in_array('magento/product-enterprise-edition', $systemPackages) + && !in_array('magento/product-b2b-edition', $systemPackages) + ) { $result = array_merge($this->getAllowedB2BVersions($currentEE), $result); } @@ -101,6 +103,8 @@ class SystemPackage } /** + * Retrieve allowed EE versions + * * @param string $currentCE * @return array */ @@ -127,49 +131,66 @@ class SystemPackage return $result; } + /** + * Retrieve allowed B2B versions + * + * @param $currentEE + * @return array + */ public function getAllowedB2BVersions($currentEE) { $result = []; - $b2bVersions = $this->infoCommand->run('magento/product-b2b-edition'); - $b2bVersionsPrepared = []; + $versions = $this->infoCommand->run('magento/product-b2b-edition'); + $versionsPrepared = []; $maxVersion = ''; - if (!is_array($b2bVersions) ) { + if (!is_array($versions) ) { return $result; } - $b2bVersions['available_versions'] = array_unique( + $versions[InfoCommand::CURRENT_VERSION] = isset($versions[InfoCommand::CURRENT_VERSION]) + ? $versions[InfoCommand::CURRENT_VERSION] + : null; + $versions[InfoCommand::AVAILABLE_VERSIONS] = isset($versions[InfoCommand::AVAILABLE_VERSIONS]) + ? $versions[InfoCommand::AVAILABLE_VERSIONS] + : []; + + $versions[InfoCommand::AVAILABLE_VERSIONS] = array_unique( array_merge( - (array)$b2bVersions['current_version'], - (array)$b2bVersions['available_versions'] + (array)$versions[InfoCommand::CURRENT_VERSION], + (array)$versions[InfoCommand::AVAILABLE_VERSIONS] ) ); - if ($b2bVersions['available_versions']) { - $b2bVersions = $this->sortVersions($b2bVersions); - if (isset($b2bVersions['available_versions'][0])) { - $maxVersion = $b2bVersions['available_versions'][0]; + if ($versions[InfoCommand::AVAILABLE_VERSIONS]) { + $versions = $this->sortVersions($versions); + if (isset($versions[InfoCommand::AVAILABLE_VERSIONS][0])) { + $maxVersion = $versions[InfoCommand::AVAILABLE_VERSIONS][0]; } - $b2bVersionsPrepared = $this->filterB2bVersions($currentEE, $b2bVersions, $maxVersion); + $versionsPrepared = $this->filterB2bVersions($currentEE, $versions, $maxVersion); } - if (!empty($b2bVersionsPrepared)) { + if ($versionsPrepared) { $result[] = [ 'package' => 'magento/product-b2b-edition', - 'versions' => $b2bVersionsPrepared, + 'versions' => $versionsPrepared, ]; } + return $result; } /** + * Retrieve package versions + * * @param array $systemPackageInfo - * @param array $versions * @return array */ - public function getSystemPackageVersions($systemPackageInfo, $versions) + public function getSystemPackageVersions($systemPackageInfo) { $editionType = ''; + $versions = []; + if ($systemPackageInfo['name'] == 'magento/product-community-edition') { $editionType .= 'CE'; } elseif ($systemPackageInfo['name'] == 'magento/product-enterprise-edition') { -- GitLab From c9c067d33ae0192e3d206a47111f5064d9d22f89 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 19 Aug 2016 10:24:12 -0500 Subject: [PATCH 544/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 #5225 - fix & add code to integration test with new logic --- .../Product/Form/Modifier/EavTest.php | 13 +++ .../_files/eav_expected_meta_output.php | 2 +- .../eav_expected_meta_output_w_default.php | 105 ++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output_w_default.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/EavTest.php index ffcf5096b10..eeba8d78cea 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -70,6 +70,19 @@ class EavTest extends \PHPUnit_Framework_TestCase $this->prepareDataForComparison($actualMeta, $expectedMeta); $this->assertEquals($expectedMeta, $actualMeta); } + + public function testModifyMetaNewProduct() + { + $this->objectManager->get(\Magento\Eav\Model\Entity\AttributeCache::class)->clear(); + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->objectManager->create(\Magento\Catalog\Model\Product::class); + $product->setAttributeSetId(4); + $this->locatorMock->expects($this->any())->method('getProduct')->willReturn($product); + $expectedMeta = include __DIR__ . '/_files/eav_expected_meta_output_w_default.php'; + $actualMeta = $this->eavModifier->modifyMeta([]); + $this->prepareDataForComparison($actualMeta, $expectedMeta); + $this->assertEquals($expectedMeta, $actualMeta); + } /** * @magentoDataFixture Magento/Catalog/_files/product_simple_with_admin_store.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php index 1f22ec3b1c6..2f2512d8e9e 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php @@ -35,7 +35,7 @@ return [ "visible" => "1", "required" => "0", "label" => "Enable Product", - "default" => "1", + "default" => null, "source" => "product-details", "scopeLabel" => "[WEBSITE]", "globalScope" => false, diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output_w_default.php b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output_w_default.php new file mode 100644 index 00000000000..999a96d2981 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output_w_default.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +return [ + "product-details" => [ + "arguments" => [ + "data" => [ + "config" => [ + "dataScope" => "data.product", + ], + ], + ], + "children" => [ + "container_status" => [ + "children" => [ + "status" => [ + "arguments" => [ + "data" => [ + "config" => [ + "dataType" => "select", + "formElement" => "select", + "options" => [ + [ + "value" => 1, + "label" => "Enabled" + ], + [ + "value" => 2, + "label" => "Disabled" + ] + ], + "visible" => "1", + "required" => "0", + "label" => "Enable Product", + "default" => "1", + "source" => "product-details", + "scopeLabel" => "[WEBSITE]", + "globalScope" => false, + "code" => "status", + "sortOrder" => "__placeholder__", + "componentType" => "field" + ], + ], + ], + ], + ], + ], + "container_name" => [ + "children" => [ + "name" => [ + "arguments" => [ + "data" => [ + "config" => [ + "dataType" => "text", + "formElement" => "input", + "visible" => "1", + "required" => "1", + "label" => "Product Name", + "source" => "product-details", + "scopeLabel" => "[STORE VIEW]", + "globalScope" => false, + "code" => "name", + "sortOrder" => "__placeholder__", + "componentType" => "field", + "validation" => [ + "required-entry" => true + ], + ], + ], + ], + ], + ], + ], + "container_sku" => [ + "children" => [ + "sku" => [ + "arguments" => [ + "data" => [ + "config" => [ + "dataType" => "text", + "formElement" => "input", + "visible" => "1", + "required" => "1", + "label" => "SKU", + "source" => "product-details", + "scopeLabel" => "[GLOBAL]", + "globalScope" => true, + "code" => "sku", + "sortOrder" => "__placeholder__", + "componentType" => "field", + "validation" => [ + "required-entry" => true + ], + ], + ], + ], + ], + ], + ], + ], + ], +]; -- GitLab From 842a693b6991cd37fe12a724f4f67bf9ae61b928 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 19 Aug 2016 18:28:38 +0300 Subject: [PATCH 545/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- .../Test/Unit/Model/SystemPackageTest.php | 105 +++++++++++++++--- 1 file changed, 88 insertions(+), 17 deletions(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php b/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php index 52995241ce0..9991b4803b3 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php @@ -320,6 +320,39 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase ); } + /** + * @param string $eeCurrentVersion + * @param array $expectedResult + * + * @dataProvider getAllowedB2bVersionsDataProvider + */ + public function testGetAllowedB2bVersions($eeCurrentVersion, $expectedResult) + { + $this->composerAppFactory->expects($this->once()) + ->method('createInfoCommand') + ->willReturn($this->infoCommand); + $this->systemPackage = new SystemPackage($this->composerAppFactory, $this->composerInformation); + $this->infoCommand->expects($this->once()) + ->method('run') + ->with('magento/product-b2b-edition') + ->willReturn(['available_versions' => ['1.0.0', '1.0.1', '1.0.2']]); + $require = $this->getMock(\Composer\Package\Link::class, [], [], '', false); + $constraintMock = $this->getMock(\Composer\Semver\Constraint\Constraint::class, [], [], '', false); + $constraintMock->expects($this->any())->method('getPrettyString') + ->willReturn('1.0.1'); + $require->expects($this->any()) + ->method('getConstraint') + ->willReturn($constraintMock); + + $this->composerInformation->expects($this->any()) + ->method('getPackageRequirements') + ->willReturn(['magento/product-enterprise-edition' => $require]); + $this->assertEquals( + $expectedResult, + $this->systemPackage->getAllowedB2BVersions($eeCurrentVersion) + ); + } + /** * @return array */ @@ -327,30 +360,68 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase { return [ ['2.0.0', []], - ['1.0.0', [ + [ + '1.0.0', [ - 'package' => 'magento/product-enterprise-edition', - 'versions' => [ - [ - 'id' => '1.0.2', - 'name' => 'Version 1.0.2 EE (latest)', - 'current' => false, - ], - [ - 'id' => '1.0.1', - 'name' => 'Version 1.0.1 EE', - 'current' => false, + [ + 'package' => 'magento/product-enterprise-edition', + 'versions' => [ + [ + 'id' => '1.0.2', + 'name' => 'Version 1.0.2 EE (latest)', + 'current' => false, + ], + [ + 'id' => '1.0.1', + 'name' => 'Version 1.0.1 EE', + 'current' => false, + ], + [ + + 'id' => '1.0.0', + 'name' => 'Version 1.0.0 EE', + 'current' => false, + ], ], - [ + ], + ], + ], + ]; + } - 'id' => '1.0.0', - 'name' => 'Version 1.0.0 EE', - 'current' => false, + /** + * @return array + */ + public function getAllowedB2bVersionsDataProvider() + { + return [ + ['2.0.0', []], + [ + '1.0.0', + [ + [ + 'package' => 'magento/product-b2b-edition', + 'versions' => [ + [ + 'id' => '1.0.2', + 'name' => 'Version 1.0.2 B2B (latest)', + 'current' => false, + ], + [ + 'id' => '1.0.1', + 'name' => 'Version 1.0.1 B2B', + 'current' => false, + ], + [ + + 'id' => '1.0.0', + 'name' => 'Version 1.0.0 B2B', + 'current' => false, + ], ], ], ], ], - ], ]; } } -- GitLab From 449b261cb0b910cfd20c0adbb7cb840bcda811fb Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Fri, 19 Aug 2016 11:11:04 -0500 Subject: [PATCH 546/838] MAGETWO-55950: Automate Create new Email Template test - fixing static code analysis comments. --- .../Test/Block/Adminhtml/Template/Edit/TemplateForm.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml index fe262774647..b8bd0ee922a 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.xml @@ -1,4 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + --> <mapping strict="1"> <fields> <template_select> -- GitLab From 37c4b9d97511de3828cac9772017cb4c7505aa82 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Fri, 19 Aug 2016 15:30:14 -0500 Subject: [PATCH 547/838] MAGETWO-56868: CLONE - Cannot save a product with images for the second time - Added unit test. --- .../Catalog/Test/Unit/Model/ProductTest.php | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php index 10bd9ddfd57..acc4512b969 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php @@ -185,6 +185,16 @@ class ProductTest extends \PHPUnit_Framework_TestCase */ private $extensionAttributesFactory; + /** + * @var \Magento\Framework\Filesystem + */ + private $filesystemMock; + + /** + * @var \Magento\Framework\Data\CollectionFactory + */ + private $collectionFactoryMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -374,6 +384,12 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->extensionAttributesFactory = $this->getMockBuilder(ExtensionAttributesFactory::class) ->disableOriginalConstructor() ->getMock(); + $this->filesystemMock = $this->getMockBuilder(\Magento\Framework\Filesystem::class) + ->disableOriginalConstructor() + ->getMock(); + $this->collectionFactoryMock = $this->getMockBuilder(\Magento\Framework\Data\CollectionFactory::class) + ->disableOriginalConstructor() + ->getMock(); $this->mediaConfig = $this->getMock(\Magento\Catalog\Model\Product\Media\Config::class, [], [], '', false); $this->objectManagerHelper = new ObjectManagerHelper($this); @@ -402,6 +418,8 @@ class ProductTest extends \PHPUnit_Framework_TestCase 'mediaGalleryEntryConverterPool' => $this->mediaGalleryEntryConverterPoolMock, 'linkRepository' => $this->productLinkRepositoryMock, 'catalogProductMediaConfig' => $this->mediaConfig, + '_filesystem' => $this->filesystemMock, + '_collectionFactory' => $this->collectionFactoryMock, 'data' => ['id' => 1] ] ); @@ -1230,6 +1248,71 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expectedResult, $this->model->getMediaGallery()); } + public function testGetMediaGalleryImagesMerging() + { + $mediaEntries = [ + 'images' => [ + [ + 'value_id' => 1, + 'file' => 'imageFile.jpg', + 'media_type' => 'image', + ], + [ + 'value_id' => 1, + 'file' => 'imageFile.jpg', + ], + [ + 'value_id' => 2, + 'file' => 'smallImageFile.jpg', + 'media_type' => 'image', + ], + ] + ]; + $expectedImageDataObject = new \Magento\Framework\DataObject([ + 'value_id' => 1, + 'file' => 'imageFile.jpg', + 'media_type' => 'image', + 'url' => 'http://magento.dev/pub/imageFile.jpg', + 'id' => 1, + 'path' => '/var/www/html/pub/imageFile.jpg', + ]); + $expectedSmallImageDataObject = new \Magento\Framework\DataObject([ + 'value_id' => 2, + 'file' => 'smallImageFile.jpg', + 'media_type' => 'image', + 'url' => 'http://magento.dev/pub/smallImageFile.jpg', + 'id' => 2, + 'path' => '/var/www/html/pub/smallImageFile.jpg', + ]); + + $directoryMock = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\ReadInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->filesystemMock->expects($this->once())->method('getDirectoryRead')->willReturn($directoryMock); + $this->model->setData('media_gallery', $mediaEntries); + $imagesCollectionMock = $this->getMockBuilder(\Magento\Framework\Data\Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($imagesCollectionMock); + $imagesCollectionMock->expects($this->at(2))->method('getItemById')->with(1)->willReturn($expectedImageDataObject); + $this->mediaConfig->expects($this->at(0)) + ->method('getMediaUrl') + ->willReturn('http://magento.dev/pub/imageFile.jpg'); + $directoryMock->expects($this->at(0)) + ->method('getAbsolutePath') + ->willReturn('/var/www/html/pub/imageFile.jpg'); + $this->mediaConfig->expects($this->at(2)) + ->method('getMediaUrl') + ->willReturn('http://magento.dev/pub/smallImageFile.jpg'); + $directoryMock->expects($this->at(1)) + ->method('getAbsolutePath') + ->willReturn('/var/www/html/pub/smallImageFile.jpg'); + $imagesCollectionMock->expects($this->at(1))->method('addItem')->with($expectedImageDataObject); + $imagesCollectionMock->expects($this->at(4))->method('addItem')->with($expectedSmallImageDataObject); + + $this->model->getMediaGalleryImages(); + } + public function testGetCustomAttributes() { $priceCode = 'price'; -- GitLab From 2cb3381579fc1fee9ab97632af70199e9224aef4 Mon Sep 17 00:00:00 2001 From: Islam Elkhalifa <ielkhalifa@magento.com> Date: Fri, 19 Aug 2016 17:19:08 -0500 Subject: [PATCH 548/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - fixing code styles. --- .../Config/Test/Block/System/Config/AdminForm.php | 13 +++++++------ .../Test/Constraint/AssertAdminAccountSharing.php | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php index 5d395e4efa4..e5f30cfc93a 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php @@ -9,16 +9,17 @@ namespace Magento\Config\Test\Block\System\Config; use Magento\Mtf\Block\Form; use Magento\Mtf\Client\Locator; -/** + /** * Admin Security form in admin configurations. * - * this class needs to be created becuase we need to check for the availability of Admin account sharing settings, This is not possible using the form block class only -*/ + * Locate Admin account sharing settings, see if its visible + */ class AdminForm extends Form { - protected $AdminAccountSharingField = "#admin_security_admin_account_sharing"; + protected $adminAccountSharingField = "#admin_security_admin_account_sharing"; - public function AdminAccountSharingAvailability() { - return $this->_rootElement->find($this->AdminAccountSharingField, Locator::SELECTOR_CSS)->isVisible(); + public function adminAccountSharingAvailability() + { + return $this->_rootElement->find($this->adminAccountSharingField, Locator::SELECTOR_CSS)->isVisible(); } } diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php index 5d30ab50cf2..2e6d41a99d3 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php @@ -20,8 +20,8 @@ class AssertAdminAccountSharing extends AbstractConstraint */ public function processAssert(AdminAccountSharing $adminAccountSharing) { - \PHPUnit_Framework_Assert::assertTrue( - $adminAccountSharing->getAdminForm()->AdminAccountSharingAvailability(), + \PHPUnit_Framework_Assert::assertTrue( + $adminAccountSharing->getAdminForm()->adminAccountSharingAvailability(), 'Admin Account Sharing Option is not available' ); } -- GitLab From 3581b20ee81adc416258140658554a883e5cc353 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Fri, 19 Aug 2016 18:32:21 -0500 Subject: [PATCH 549/838] MAGETWO-56868: CLONE - Cannot save a product with images for the second time - Static & unit test fixes. --- app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php | 1 + .../app/Magento/Config/Test/Block/System/Config/AdminForm.php | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php index acc4512b969..d4950d9df6d 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php @@ -389,6 +389,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->collectionFactoryMock = $this->getMockBuilder(\Magento\Framework\Data\CollectionFactory::class) ->disableOriginalConstructor() + ->setMethods(['create']) ->getMock(); $this->mediaConfig = $this->getMock(\Magento\Catalog\Model\Product\Media\Config::class, [], [], '', false); $this->objectManagerHelper = new ObjectManagerHelper($this); diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php index e5f30cfc93a..f694e93689d 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php @@ -3,13 +3,12 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Config\Test\Block\System\Config; use Magento\Mtf\Block\Form; use Magento\Mtf\Client\Locator; - /** +/** * Admin Security form in admin configurations. * * Locate Admin account sharing settings, see if its visible -- GitLab From af84ce516d3678bb026841402de93b168559f71e Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 22 Aug 2016 10:15:51 +0300 Subject: [PATCH 550/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Category/Plugin/Category/Move.php | 2 ++ .../Model/Category/Plugin/Store/Group.php | 2 ++ .../Model/Category/Plugin/Store/View.php | 9 +++++++++ .../Model/Category/Plugin/Category/MoveTest.php | 14 +++++++------- .../Model/Category/Plugin/Category/RemoveTest.php | 13 ++++++------- .../Unit/Model/Category/Plugin/Store/GroupTest.php | 2 +- .../Unit/Model/Category/Plugin/Store/ViewTest.php | 12 ++++++------ .../Product/Link/RelationPersister.php | 4 +++- .../Product/Link/RelationPersisterTest.php | 10 ++++++---- .../Newsletter/Model/Plugin/CustomerPlugin.php | 1 + .../Test/Unit/Model/Plugin/CustomerPluginTest.php | 6 ++++-- 11 files changed, 47 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php index 7a4c94dde0c..4175a7ddb4e 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Category/Move.php @@ -32,6 +32,8 @@ class Move } /** + * Perform url updating for children categories + * * @param \Magento\Catalog\Model\ResourceModel\Category $subject * @param \Magento\Catalog\Model\ResourceModel\Category $result * @param Category $category diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php index c290d10296e..1b18385d4a6 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/Group.php @@ -63,6 +63,8 @@ class Group } /** + * Perform updating url for categories and products assigned to the group + * * @param \Magento\Store\Model\ResourceModel\Group $subject * @param \Magento\Store\Model\ResourceModel\Group $result * @param AbstractModel $group diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php index a181e685925..ea28b20f3f8 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php @@ -52,6 +52,8 @@ class View } /** + * Perform updating url for categories and products assigned to the store view + * * @param \Magento\Store\Model\ResourceModel\Store $subject * @param \Magento\Store\Model\ResourceModel\Store $result * @param AbstractModel $store @@ -76,6 +78,7 @@ class View $this->generateProductUrls($store->getWebsiteId(), $store->getOrigData('website_id'), $store->getId()) ); } + return $result; } @@ -98,6 +101,7 @@ class View ->addCategoryIds() ->addAttributeToSelect(['name', 'url_path', 'url_key', 'visibility']) ->addWebsiteFilter($websiteIds); + foreach ($collection as $product) { $product->setStoreId($storeId); /** @var \Magento\Catalog\Model\Product $product */ @@ -106,6 +110,7 @@ class View $this->productUrlRewriteGenerator->generate($product) ); } + return $urls; } @@ -126,10 +131,13 @@ class View $this->categoryUrlRewriteGenerator->generate($category) ); } + return $urls; } /** + * Delete unused url rewrites + * * @param \Magento\Store\Model\ResourceModel\Store $subject * @param \Magento\Store\Model\ResourceModel\Store $result * @param AbstractModel $store @@ -142,6 +150,7 @@ class View AbstractModel $store ) { $this->urlPersist->deleteByData([UrlRewrite::STORE_ID => $store->getId()]); + return $result; } } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php index a3a09e9c42f..7fe042232b8 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/MoveTest.php @@ -5,11 +5,11 @@ */ namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Category; -use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Move; +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Move as CategoryMovePlugin; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; -use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; +use Magento\Catalog\Model\ResourceModel\Category as CategoryResourceModel; use Magento\Catalog\Model\Category; class MoveTest extends \PHPUnit_Framework_TestCase @@ -30,7 +30,7 @@ class MoveTest extends \PHPUnit_Framework_TestCase private $categoryUrlPathGeneratorMock; /** - * @var ResourceCategory|\PHPUnit_Framework_MockObject_MockObject + * @var CategoryResourceModel|\PHPUnit_Framework_MockObject_MockObject */ private $subjectMock; @@ -40,7 +40,7 @@ class MoveTest extends \PHPUnit_Framework_TestCase private $categoryMock; /** - * @var Move + * @var CategoryMovePlugin */ private $plugin; @@ -55,7 +55,7 @@ class MoveTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['getChildren']) ->getMock(); - $this->subjectMock = $this->getMockBuilder(ResourceCategory::class) + $this->subjectMock = $this->getMockBuilder(CategoryResourceModel::class) ->disableOriginalConstructor() ->getMock(); $this->categoryMock = $this->getMockBuilder(Category::class) @@ -63,7 +63,7 @@ class MoveTest extends \PHPUnit_Framework_TestCase ->setMethods(['getResource', 'setUrlPath']) ->getMock(); $this->plugin = $this->objectManager->getObject( - Move::class, + CategoryMovePlugin::class, [ 'categoryUrlPathGenerator' => $this->categoryUrlPathGeneratorMock, 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock @@ -91,7 +91,7 @@ class MoveTest extends \PHPUnit_Framework_TestCase $this->categoryMock->expects($this->once()) ->method('setUrlPath') ->with($urlPath); - $this->assertEquals( + $this->assertSame( $this->subjectMock, $this->plugin->afterChangeParent( $this->subjectMock, diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php index 04dcffb4f8e..520975871bf 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Category/RemoveTest.php @@ -5,13 +5,12 @@ */ namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Category; -use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Remove; +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Category\Remove as CategoryRemovePlugin; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\UrlRewrite\Model\UrlPersistInterface; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; -use Magento\Catalog\Model\ResourceModel\Category as ResourceCategory; +use Magento\Catalog\Model\ResourceModel\Category as CategoryResourceModel; use Magento\Catalog\Model\Category; -use Magento\Catalog\Api\Data\CategoryInterface; class RemoveTest extends \PHPUnit_Framework_TestCase { @@ -31,7 +30,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase private $childrenCategoriesProviderMock; /** - * @var ResourceCategory|\PHPUnit_Framework_MockObject_MockObject + * @var CategoryResourceModel|\PHPUnit_Framework_MockObject_MockObject */ private $subjectMock; @@ -47,7 +46,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase ->getMockForAbstractClass(); $this->childrenCategoriesProviderMock = $this->getMockBuilder(ChildrenCategoriesProvider::class) ->getMock(); - $this->subjectMock = $this->getMockBuilder(ResourceCategory::class) + $this->subjectMock = $this->getMockBuilder(CategoryResourceModel::class) ->disableOriginalConstructor() ->getMock(); $this->objectMock = $this->getMockBuilder(Category::class) @@ -62,7 +61,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase return $closureSubject; }; $plugin = $this->objectManager->getObject( - Remove::class, + CategoryRemovePlugin::class, [ 'urlPersist' => $this->urlPersistMock, 'childrenCategoriesProvider' => $this->childrenCategoriesProviderMock @@ -77,7 +76,7 @@ class RemoveTest extends \PHPUnit_Framework_TestCase ->willReturn(1); $this->urlPersistMock->expects($this->exactly(2)) ->method('deleteByData'); - $this->assertEquals( + $this->assertSame( $this->subjectMock, $plugin->aroundDelete($this->subjectMock, $proceed, $this->objectMock) ); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php index 65f65f3f3ce..dc69597ef6d 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/GroupTest.php @@ -170,7 +170,7 @@ class GroupTest extends \PHPUnit_Framework_TestCase ->with($this->productMock) ->willReturn([]); - $this->assertEquals( + $this->assertSame( $this->subjectMock, $this->plugin->afterSave($this->subjectMock, $this->subjectMock, $this->abstractModelMock) ); diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php index 9eb41826f78..d30c2dde6e0 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php @@ -5,7 +5,7 @@ */ namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Store; -use Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\View; +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\View as StoreViewPlugin; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\Model\AbstractModel; use Magento\Store\Model\ResourceModel\Store; @@ -16,7 +16,7 @@ use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator; use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; use Magento\Catalog\Model\Category; use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; -use Magento\Catalog\Model\Product as Product; +use Magento\Catalog\Model\Product; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -29,7 +29,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase private $objectManager; /** - * @var View + * @var StoreViewPlugin */ private $plugin; @@ -124,7 +124,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase ->setMethods(['getCollection']) ->getMock(); $this->plugin = $this->objectManager->getObject( - View::class, + StoreViewPlugin::class, [ 'urlPersist' => $this->urlPersistMock, 'categoryFactory' => $this->categoryFactoryMock, @@ -170,7 +170,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase ->with($this->productMock) ->willReturn([]); - $this->assertEquals( + $this->assertSame( $this->subjectMock, $this->plugin->afterSave($this->subjectMock, $this->subjectMock, $this->abstractModelMock) ); @@ -180,7 +180,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase { $this->urlPersistMock->expects($this->once()) ->method('deleteByData'); - $this->assertEquals( + $this->assertSame( $this->subjectMock, $this->plugin->afterDelete($this->subjectMock, $this->subjectMock, $this->abstractModelMock) ); diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php index fe937abfe59..f431bf3af95 100644 --- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php +++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Link/RelationPersister.php @@ -36,6 +36,8 @@ class RelationPersister } /** + * Save grouped products to product relation table + * * @param Link $subject * @param Link $result * @param int $parentId @@ -44,7 +46,7 @@ class RelationPersister * @return Link * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterSaveProductLinks(Link $subject, Link $result, $parentId, array $data, $typeId) + public function afterSaveProductLinks(Link $subject, Link $result, $parentId, $data, $typeId) { if ($typeId == GroupedLink::LINK_TYPE_GROUPED) { foreach ($data as $linkData) { diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php index 4eded50bcf0..49bcd76cc2b 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ResourceModel/Product/Link/RelationPersisterTest.php @@ -10,7 +10,7 @@ use Magento\Catalog\Model\ProductLink\LinkFactory; use Magento\Catalog\Model\Product\Link; use Magento\Catalog\Model\ResourceModel\Product\Relation; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\Catalog\Model\ResourceModel\Product\Link as ResourceLink; +use Magento\Catalog\Model\ResourceModel\Product\Link as LinkResourceModel; class RelationPersisterTest extends \PHPUnit_Framework_TestCase { @@ -23,7 +23,9 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase /** @var Relation */ private $relationProcessor; - /** @var ObjectManager */ + /** + * @var ObjectManager + */ private $objectManager; /** @@ -32,7 +34,7 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase private $linkFactory; /** - * @var ResourceLink|\PHPUnit_Framework_MockObject_MockObject + * @var LinkResourceModel|\PHPUnit_Framework_MockObject_MockObject */ private $subject; @@ -59,7 +61,7 @@ class RelationPersisterTest extends \PHPUnit_Framework_TestCase $this->linkFactory->expects($this->any())->method('create')->willReturn($this->link); - $this->subject = $this->getMockBuilder(ResourceLink::class) + $this->subject = $this->getMockBuilder(LinkResourceModel::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php index 5aeb3d284d7..3cae720825a 100644 --- a/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php +++ b/app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php @@ -30,6 +30,7 @@ class CustomerPlugin /** * Plugin after create customer that updates any newsletter subscription that may have existed. + * * If we have extension attribute (is_subscribed) we need to subscribe that customer * * @param CustomerRepository $subject diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php index 0b874de7b70..458d6ea22b0 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php @@ -78,7 +78,7 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase /** * @return array */ - public function provideExtensionAttributeDataForAfterSave() + public function afterSaveExtensionAttributeDataProvider() { return [ [true, true], @@ -87,7 +87,9 @@ class CustomerPluginTest extends \PHPUnit_Framework_TestCase } /** - * @dataProvider provideExtensionAttributeDataForAfterSave + * @param boolean $isSubscribed + * @param boolean $subscribeIsCreated + * @dataProvider afterSaveExtensionAttributeDataProvider */ public function testAfterSaveWithIsSubscribed($isSubscribed, $subscribeIsCreated) { -- GitLab From 097dff107f81a9092a4e3f411f0e550adf1855b6 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 22 Aug 2016 11:08:50 +0300 Subject: [PATCH 551/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- .../src/Magento/Setup/Model/SystemPackage.php | 54 +++++++----- .../Test/Unit/Model/SystemPackageTest.php | 87 +++++++++++-------- 2 files changed, 87 insertions(+), 54 deletions(-) diff --git a/setup/src/Magento/Setup/Model/SystemPackage.php b/setup/src/Magento/Setup/Model/SystemPackage.php index 38249555380..de2df00347c 100755 --- a/setup/src/Magento/Setup/Model/SystemPackage.php +++ b/setup/src/Magento/Setup/Model/SystemPackage.php @@ -134,34 +134,16 @@ class SystemPackage /** * Retrieve allowed B2B versions * - * @param $currentEE + * @param string $currentEE * @return array */ public function getAllowedB2BVersions($currentEE) { $result = []; - $versions = $this->infoCommand->run('magento/product-b2b-edition'); + $versions = $this->fetchInfoVersions('magento/product-b2b-edition'); $versionsPrepared = []; $maxVersion = ''; - if (!is_array($versions) ) { - return $result; - } - - $versions[InfoCommand::CURRENT_VERSION] = isset($versions[InfoCommand::CURRENT_VERSION]) - ? $versions[InfoCommand::CURRENT_VERSION] - : null; - $versions[InfoCommand::AVAILABLE_VERSIONS] = isset($versions[InfoCommand::AVAILABLE_VERSIONS]) - ? $versions[InfoCommand::AVAILABLE_VERSIONS] - : []; - - $versions[InfoCommand::AVAILABLE_VERSIONS] = array_unique( - array_merge( - (array)$versions[InfoCommand::CURRENT_VERSION], - (array)$versions[InfoCommand::AVAILABLE_VERSIONS] - ) - ); - if ($versions[InfoCommand::AVAILABLE_VERSIONS]) { $versions = $this->sortVersions($versions); if (isset($versions[InfoCommand::AVAILABLE_VERSIONS][0])) { @@ -180,6 +162,30 @@ class SystemPackage return $result; } + /** + * Fetching info command response to + * display all correct versions + * + * @param string $command + * @return array + */ + private function fetchInfoVersions($command) + { + $versions = (array)$this->infoCommand->run($command); + + $versions[InfoCommand::CURRENT_VERSION] = isset($versions[InfoCommand::CURRENT_VERSION]) + ? $versions[InfoCommand::CURRENT_VERSION] + : null; + $versions[InfoCommand::AVAILABLE_VERSIONS] = array_unique( + array_merge( + (array)$versions[InfoCommand::CURRENT_VERSION], + (array)$versions[InfoCommand::AVAILABLE_VERSIONS] + ) + ); + + return $versions; + } + /** * Retrieve package versions * @@ -331,6 +337,14 @@ class SystemPackage return $eeVersions; } + /** + * Filtering B2B versions + * + * @param string $currentEE + * @param array $b2bVersions + * @param string $maxVersion + * @return array + */ public function filterB2bVersions($currentEE, $b2bVersions, $maxVersion) { $b2bVersionsPrepared = []; diff --git a/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php b/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php index 9991b4803b3..bf9839495a8 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php @@ -176,43 +176,62 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $this->systemPackage = new SystemPackage($this->composerAppFactory, $this->composerInformation); - $this->infoCommand->expects($this->at(0)) + $this->infoCommand->expects($this->any()) ->method('run') - ->with('magento/product-community-edition') - ->willReturn( + ->willReturnMap([ [ - 'name' => 'magento/product-community-edition', - 'description' => 'eCommerce Platform for Growth (Enterprise Edition)', - 'keywords' => '', - 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', - 'type' => 'metapackage', - 'license' => 'OSL-3.0, AFL-3.0', - 'source' => '[]', - 'names' => 'magento/product-community-edition', - 'current_version' => '1.0.0', - 'available_versions' => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], - 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], - ] - ); - - $this->infoCommand->expects($this->at(1)) - ->method('run') - ->with('magento/product-enterprise-edition') - ->willReturn( + 'magento/product-community-edition', + false, + [ + 'name' => 'magento/product-community-edition', + 'description' => 'eCommerce Platform for Growth (Enterprise Edition)', + 'keywords' => '', + 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', + 'type' => 'metapackage', + 'license' => 'OSL-3.0, AFL-3.0', + 'source' => '[]', + 'names' => 'magento/product-community-edition', + 'current_version' => '1.0.0', + 'available_versions' => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], + 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], + ], + ], [ - 'name' => 'magento/product-enterprise-edition', - 'description' => 'eCommerce Platform for Growth (Enterprise Edition)', - 'keywords' => '', - 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', - 'type' => 'metapackage', - 'license' => 'OSL-3.0, AFL-3.0', - 'source' => '[]', - 'names' => 'magento/product-enterprise-edition', - 'current_version' => '1.0.0', - 'available_versions' => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], - 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], - ] - ); + 'magento/product-enterprise-edition', + false, + [ + 'name' => 'magento/product-enterprise-edition', + 'description' => 'eCommerce Platform for Growth (Enterprise Edition)', + 'keywords' => '', + 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', + 'type' => 'metapackage', + 'license' => 'OSL-3.0, AFL-3.0', + 'source' => '[]', + 'names' => 'magento/product-enterprise-edition', + 'current_version' => '1.0.0', + 'available_versions' => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], + 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], + ], + + ], + [ + + 'magento/product-b2b-edition', + false, + [ + 'name' => 'magento/product-b2b-edition', + 'description' => 'eCommerce Platform for Growth (B2B Edition)', + 'keywords' => '', + 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', + 'type' => 'metapackage', + 'license' => 'OSL-3.0, AFL-3.0', + 'source' => '[]', + 'names' => 'magento/product-b2b-edition', + 'available_versions' => [], + 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], + ], + ], + ]); $this->assertEquals($this->expectedPackages, $this->systemPackage->getPackageVersions()); } -- GitLab From 1b0ce3d6b897ad1130bae5cf2a21fdfe467ec31d Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 22 Aug 2016 11:19:49 +0300 Subject: [PATCH 552/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Test/Unit/Plugin/DbStatusValidatorTest.php | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php index fee05056081..c0563020110 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php @@ -21,11 +21,6 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase */ protected $_cacheMock; - /** - * @var \Closure - */ - protected $closureMock; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -49,9 +44,6 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase protected function setUp() { $this->_cacheMock = $this->getMock(\Magento\Framework\Cache\FrontendInterface::class); - $this->closureMock = function () { - return 'Expected'; - }; $this->requestMock = $this->getMock(\Magento\Framework\App\RequestInterface::class); $this->subjectMock = $this->getMock(\Magento\Framework\App\FrontController::class, [], [], '', false); $moduleList = $this->getMockForAbstractClass(\Magento\Framework\Module\ModuleListInterface::class); @@ -85,8 +77,8 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase ->will($this->returnValueMap($returnMap)); $this->assertEquals( - 'Expected', - $this->_model->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) + null, + $this->_model->beforeDispatch($this->subjectMock, $this->requestMock) ); } @@ -101,8 +93,8 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase $this->moduleManager->expects($this->never()) ->method('isDbDataUpToDate'); $this->assertEquals( - 'Expected', - $this->_model->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) + null, + $this->_model->beforeDispatch($this->subjectMock, $this->requestMock) ); } @@ -125,7 +117,7 @@ class DbStatusValidatorTest extends \PHPUnit_Framework_TestCase ->method('getDbVersionErrors') ->will($this->returnValue($dbVersionErrors)); - $this->_model->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock); + $this->_model->beforeDispatch($this->subjectMock, $this->requestMock); } /** -- GitLab From 76defb9a61afb4b2d6865fbd3fae4c5dddb34fa9 Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Mon, 22 Aug 2016 12:21:39 +0300 Subject: [PATCH 553/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- app/code/Magento/CatalogInventory/etc/di.xml | 2 +- app/code/Magento/ConfigurableProduct/etc/di.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml index cfd47ea1466..9a70e79371f 100644 --- a/app/code/Magento/CatalogInventory/etc/di.xml +++ b/app/code/Magento/CatalogInventory/etc/di.xml @@ -72,6 +72,6 @@ <plugin name="catalogInventoryAfterLoad" type="\Magento\CatalogInventory\Model\Plugin\AfterProductLoad"/> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="catalogInventoryAroundSave" type="\Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="catalogInventoryAroundSave" sortOrder="2" type="\Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/> </type> </config> diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index e32286764f5..64964baab1d 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -59,7 +59,7 @@ </arguments> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="configurableProductSaveOptions" type="\Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="configurableProductSaveOptions" sortOrder="1" type="\Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> </type> <type name="Magento\Catalog\Model\Product"> <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" /> -- GitLab From 92455b59635a75ef7ed5791d99f0618ad76c5f51 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Mon, 22 Aug 2016 12:22:59 +0300 Subject: [PATCH 554/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Paypal/Test/Unit/Model/Config/StructurePluginTest.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php index 3b639bca2c8..63abcd66042 100644 --- a/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Model/Config/StructurePluginTest.php @@ -116,11 +116,10 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase /** * @param array $pathParts * @param string $countryCode - * @param array $expectedPathParts * * @dataProvider aroundGetElementByPathPartsDataProvider */ - public function testAroundGetElementByPathPartsNoResult($pathParts, $countryCode, $expectedPathParts) + public function testAroundGetElementByPathPartsNoResult($pathParts, $countryCode) { $proceed = function () { return null; @@ -139,11 +138,10 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase /** * @param array $pathParts * @param string $countryCode - * @param array $expectedPathParts * * @dataProvider aroundGetElementByPathPartsDataProvider */ - public function testAroundGetElementByPathParts($pathParts, $countryCode, $expectedPathParts) + public function testAroundGetElementByPathParts($pathParts, $countryCode) { $result = $this->elementConfigStructureMock; $proceed = function () use ($result) { @@ -169,12 +167,10 @@ class StructurePluginTest extends \PHPUnit_Framework_TestCase [ ['payment', 'group1', 'group2', 'field'], 'any', - ['payment_other', 'group1', 'group2', 'field'], ], [ ['payment', 'group1', 'group2', 'field'], 'DE', - ['payment_de', 'group1', 'group2', 'field'] ] ]; } -- GitLab From 782111e68ebc573796d9f443b235e6ccd38c14b6 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Mon, 22 Aug 2016 13:23:22 +0300 Subject: [PATCH 555/838] MAGETWO-55394: [WCAG 2.0] Add role="alert" to All Messages Appearing On the Storefront - Merge remote-tracking branch 'origin' into MAGETWO-55394 - Conflicts: - app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml --- .../Cookie/view/frontend/templates/html/notices.phtml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 948addc92ef..f7aaf538ae9 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -32,10 +32,10 @@ "#notice-cookie-block": { "cookieNotices": { "cookieAllowButtonSelector": "#btn-cookie-allow", - "cookieName": "<?php /* @escapeNotVerified */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", - "cookieValue": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>, - "cookieLifetime": <?php /* @escapeNotVerified */ echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>, - "noCookiesUrl": "<?php /* @escapeNotVerified */ echo $block->getUrl('cookie/index/noCookies') ?>" + "cookieName": "<?php /* @noEscape */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", + "cookieValue": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getAcceptedSaveCookiesWebsiteIds() ?>, + "cookieLifetime": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getCookieRestrictionLifetime()?>, + "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" } } } -- GitLab From 376e29e49e94322a611ade0dabd2f3a73ab68c8e Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Mon, 22 Aug 2016 15:34:19 +0300 Subject: [PATCH 556/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Message/Multishipping/Plugin/ItemsBox.php | 14 +++++++------- .../Magento/GiftMessage/Model/Plugin/QuoteItem.php | 8 ++++---- .../Test/Unit/Model/Plugin/QuoteItemTest.php | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php b/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php index fc0b1caebef..acc5fb484ad 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php +++ b/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php @@ -5,8 +5,8 @@ */ namespace Magento\GiftMessage\Block\Message\Multishipping\Plugin; -use Magento\Multishipping\Block\Checkout\Shipping; -use Magento\GiftMessage\Helper\Message as HelperMessage; +use Magento\Multishipping\Block\Checkout\Shipping as ShippingBlock; +use Magento\GiftMessage\Helper\Message as MessageHelper; use Magento\Framework\DataObject; /** @@ -17,16 +17,16 @@ class ItemsBox /** * Gift message helper * - * @var HelperMessage + * @var MessageHelper */ protected $helper; /** * Construct * - * @param HelperMessage $helper + * @param MessageHelper $helper */ - public function __construct(HelperMessage $helper) + public function __construct(MessageHelper $helper) { $this->helper = $helper; } @@ -34,14 +34,14 @@ class ItemsBox /** * Get items box message text for multishipping * - * @param Shipping $subject + * @param ShippingBlock $subject * @param string $itemsBoxText * @param DataObject $addressEntity * * @return string * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetItemsBoxTextAfter(Shipping $subject, $itemsBoxText, DataObject $addressEntity) + public function afterGetItemsBoxTextAfter(ShippingBlock $subject, $itemsBoxText, DataObject $addressEntity) { return $itemsBoxText . $this->helper->getInline('multishipping_address', $addressEntity); } diff --git a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php index 6a8c2191cf9..6367fd7ced4 100644 --- a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php +++ b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php @@ -6,21 +6,21 @@ namespace Magento\GiftMessage\Model\Plugin; use Magento\Sales\Api\Data\OrderItemInterface; -use Magento\GiftMessage\Helper\Message as HelperMessage; +use Magento\GiftMessage\Helper\Message as MessageHelper; use Magento\Quote\Model\Quote\Item\ToOrderItem; use Magento\Quote\Model\Quote\Item\AbstractItem; class QuoteItem { /** - * @var HelperMessage + * @var MessageHelper */ protected $_helper; /** - * @param HelperMessage $helper + * @param MessageHelper $helper */ - public function __construct(HelperMessage $helper) + public function __construct(MessageHelper $helper) { $this->_helper = $helper; } diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php index 91fa2575ed3..cfb8f1463d6 100644 --- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php +++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php @@ -68,7 +68,7 @@ class QuoteItemTest extends \PHPUnit_Framework_TestCase $this->model = new \Magento\GiftMessage\Model\Plugin\QuoteItem($this->helperMock); } - public function testAroundItemToOrderItem() + public function testAfterItemToOrderItem() { $storeId = 1; $giftMessageId = 1; -- GitLab From ff2a3668fb980241fdc406fb77f489588fbf0ea6 Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Mon, 22 Aug 2016 15:38:11 +0300 Subject: [PATCH 557/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- app/code/Magento/CatalogInventory/etc/di.xml | 2 +- app/code/Magento/ConfigurableProduct/etc/di.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml index 9a70e79371f..763a7508881 100644 --- a/app/code/Magento/CatalogInventory/etc/di.xml +++ b/app/code/Magento/CatalogInventory/etc/di.xml @@ -72,6 +72,6 @@ <plugin name="catalogInventoryAfterLoad" type="\Magento\CatalogInventory\Model\Plugin\AfterProductLoad"/> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="catalogInventoryAroundSave" sortOrder="2" type="\Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="catalogInventoryAroundSave" sortOrder="20" type="\Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/> </type> </config> diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index 64964baab1d..f8bfd3a7783 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -59,7 +59,7 @@ </arguments> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="configurableProductSaveOptions" sortOrder="1" type="\Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="configurableProductSaveOptions" sortOrder="10" type="\Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> </type> <type name="Magento\Catalog\Model\Product"> <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" /> -- GitLab From e3068d223b69b02bcc5ca2d3a0cb91b2286f1b91 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Mon, 22 Aug 2016 15:39:00 +0300 Subject: [PATCH 558/838] MAGETWO-53370: Swatches not displayed when using search --- .../layout/catalogsearch_advanced_result.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 app/code/Magento/Swatches/view/frontend/layout/catalogsearch_advanced_result.xml diff --git a/app/code/Magento/Swatches/view/frontend/layout/catalogsearch_advanced_result.xml b/app/code/Magento/Swatches/view/frontend/layout/catalogsearch_advanced_result.xml new file mode 100644 index 00000000000..3b17bac8e15 --- /dev/null +++ b/app/code/Magento/Swatches/view/frontend/layout/catalogsearch_advanced_result.xml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <css src="Magento_Swatches::css/swatches.css"/> + </head> + <body> + <referenceBlock name="category.product.type.details.renderers"> + <block class="Magento\Swatches\Block\Product\Renderer\Listing\Configurable" as="configurable" template="Magento_Swatches::product/listing/renderer.phtml" /> + </referenceBlock> + </body> +</page> -- GitLab From 313ba8e31c8ef6a1f2676b212e944f7fa943ee7e Mon Sep 17 00:00:00 2001 From: Viktor Paladiychuk <vpaladiychuk@magento.com> Date: Mon, 22 Aug 2016 15:52:35 +0300 Subject: [PATCH 559/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- app/code/Magento/CatalogInventory/etc/di.xml | 2 +- app/code/Magento/ConfigurableProduct/etc/di.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml index 763a7508881..eb97aa454f6 100644 --- a/app/code/Magento/CatalogInventory/etc/di.xml +++ b/app/code/Magento/CatalogInventory/etc/di.xml @@ -72,6 +72,6 @@ <plugin name="catalogInventoryAfterLoad" type="\Magento\CatalogInventory\Model\Plugin\AfterProductLoad"/> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="catalogInventoryAroundSave" sortOrder="20" type="\Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="catalogInventoryAroundSave" sortOrder="20" type="Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/> </type> </config> diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index f8bfd3a7783..8e793925e1c 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -59,7 +59,7 @@ </arguments> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="configurableProductSaveOptions" sortOrder="10" type="\Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="configurableProductSaveOptions" sortOrder="10" type="Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> </type> <type name="Magento\Catalog\Model\Product"> <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" /> -- GitLab From 3f8a284e607857709e2c0c765f79cd72f1e8f3bd Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Mon, 22 Aug 2016 16:20:11 +0300 Subject: [PATCH 560/838] MAGETWO-56819: Notification messages area. Pull request preparation. --- .../Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml | 2 +- .../tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml | 2 +- .../tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml | 2 +- .../app/Magento/Customer/Test/Page/Adminhtml/CustomerIndex.xml | 2 +- .../tests/app/Magento/Sales/Test/Page/Adminhtml/OrderIndex.xml | 2 +- .../Magento/Search/Test/Page/Adminhtml/SynonymGroupIndex.xml | 2 +- .../app/Magento/Shipping/Test/Page/Adminhtml/ShipmentIndex.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml index a1de0d55995..c6a125bfd4e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml @@ -7,7 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="CatalogProductIndex" area="Adminhtml" mca="catalog/product/index" module="Magento_Catalog"> - <block name="productGrid" class="Magento\Catalog\Test\Block\Adminhtml\Product\Grid" locator=".admin__data-grid-outer-wrap" strategy="css selector"/> + <block name="productGrid" class="Magento\Catalog\Test\Block\Adminhtml\Product\Grid" locator="//div[contains(@data-bind, 'product_listing')]" strategy="xpath"/> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector"/> <block name="gridPageActionBlock" class="Magento\Catalog\Test\Block\Adminhtml\Product\GridPageAction" locator="#add_new_product" strategy="css selector"/> </page> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml index e23472508e8..c369a950df3 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsBlockIndex.xml @@ -9,6 +9,6 @@ <page name="CmsBlockIndex" area="Adminhtml" mca="cms/block/index" module="Magento_Cms"> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" /> <block name="gridPageActions" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" /> - <block name="cmsBlockGrid" class="Magento\Cms\Test\Block\Adminhtml\Block\CmsGrid" locator=".admin__data-grid-outer-wrap" strategy="css selector" /> + <block name="cmsBlockGrid" class="Magento\Cms\Test\Block\Adminhtml\Block\CmsGrid" locator="//div[contains(@data-bind, 'cms_block_listing')]" strategy="xpath" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml index ed2037cf893..467d8f8a2ff 100644 --- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/Adminhtml/CmsPageIndex.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="CmsPageIndex" area="Adminhtml" mca="cms/page/index" module="Magento_Cms"> <block name="pageActionsBlock" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" /> - <block name="cmsPageGridBlock" class="Magento\Cms\Test\Block\Adminhtml\Page\Grid" locator=".admin__data-grid-outer-wrap" strategy="css selector" /> + <block name="cmsPageGridBlock" class="Magento\Cms\Test\Block\Adminhtml\Page\Grid" locator="//div[contains(@data-bind, 'cms_page_listing')]" strategy="xpath" /> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerIndex.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerIndex.xml index d0247118d2d..7b908210b6e 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerIndex.xml @@ -9,6 +9,6 @@ <page name="CustomerIndex" area="Adminhtml" mca="customer/index" module="Magento_Customer"> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector"/> <block name="pageActionsBlock" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector"/> - <block name="customerGridBlock" class="Magento\Customer\Test\Block\Adminhtml\CustomerGrid" locator=".admin__data-grid-outer-wrap" strategy="css selector"/> + <block name="customerGridBlock" class="Magento\Customer\Test\Block\Adminhtml\CustomerGrid" locator="//div[contains(@data-bind, 'customer_listing')]" strategy="xpath"/> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/OrderIndex.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/OrderIndex.xml index 1382f1c2567..beee22011c6 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/OrderIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/OrderIndex.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="OrderIndex" area="Adminhtml" mca="sales/order/index" module="Magento_Sales"> <block name="gridPageActions" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector"/> - <block name="salesOrderGrid" class="Magento\Sales\Test\Block\Adminhtml\Order\Grid" locator=".admin__data-grid-outer-wrap" strategy="css selector"/> + <block name="salesOrderGrid" class="Magento\Sales\Test\Block\Adminhtml\Order\Grid" locator="//div[contains(@data-bind, 'sales_order_grid')]" strategy="xpath"/> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector"/> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/Page/Adminhtml/SynonymGroupIndex.xml b/dev/tests/functional/tests/app/Magento/Search/Test/Page/Adminhtml/SynonymGroupIndex.xml index 85cc69ea565..a979454142f 100644 --- a/dev/tests/functional/tests/app/Magento/Search/Test/Page/Adminhtml/SynonymGroupIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Search/Test/Page/Adminhtml/SynonymGroupIndex.xml @@ -9,6 +9,6 @@ <page name="synonymGroupIndex" area="Adminhtml" mca="search/synonyms/index" module="Magento_Search"> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator=".messages .message" strategy="css selector" /> <block name="gridPageActions" class="Magento\Backend\Test\Block\GridPageActions" locator=".page-main-actions" strategy="css selector" /> - <block name="synonymGroupGrid" class="Magento\Search\Test\Block\Adminhtml\Block\SynonymGroupGrid" locator=".admin__data-grid-outer-wrap" strategy="css selector" /> + <block name="synonymGroupGrid" class="Magento\Search\Test\Block\Adminhtml\Block\SynonymGroupGrid" locator="//div[contains(@data-bind, 'search_synonyms_grid')]" strategy="xpath" /> </page> </config> diff --git a/dev/tests/functional/tests/app/Magento/Shipping/Test/Page/Adminhtml/ShipmentIndex.xml b/dev/tests/functional/tests/app/Magento/Shipping/Test/Page/Adminhtml/ShipmentIndex.xml index 81667dbbcc5..e9d5e1d2117 100644 --- a/dev/tests/functional/tests/app/Magento/Shipping/Test/Page/Adminhtml/ShipmentIndex.xml +++ b/dev/tests/functional/tests/app/Magento/Shipping/Test/Page/Adminhtml/ShipmentIndex.xml @@ -7,7 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="ShipmentIndex" area="Adminhtml" mca="sales/shipment" module="Magento_Shipping"> - <block name="shipmentsGrid" class="Magento\Shipping\Test\Block\Adminhtml\Shipment\Grid" locator=".admin__data-grid-outer-wrap" strategy="css selector"/> + <block name="shipmentsGrid" class="Magento\Shipping\Test\Block\Adminhtml\Shipment\Grid" locator="//div[contains(@data-bind, 'sales_order_shipment_grid')]" strategy="xpath"/> <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages" strategy="css selector"/> </page> </config> -- GitLab From 7024f85689521aefc64084d020404c6b9403f42a Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Mon, 22 Aug 2016 16:37:08 +0300 Subject: [PATCH 561/838] MAGETWO-56819: Notification messages area. Pull request preparation. --- .../Braintree/Test/Page/Adminhtml/BraintreeSettlementReport.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/Page/Adminhtml/BraintreeSettlementReport.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/Page/Adminhtml/BraintreeSettlementReport.xml index 20359c41bd5..bd2a0e60b20 100644 --- a/dev/tests/functional/tests/app/Magento/Braintree/Test/Page/Adminhtml/BraintreeSettlementReport.xml +++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/Page/Adminhtml/BraintreeSettlementReport.xml @@ -7,6 +7,6 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd"> <page name="BraintreeSettlementReportIndex" area="Adminhtml" mca="braintree/report/index" module="Magento_Braintree"> - <block name="settlementReportGrid" class="Magento\Braintree\Test\Block\Adminhtml\Report\Grid" locator=".admin__data-grid-outer-wrap" strategy="css selector"/> + <block name="settlementReportGrid" class="Magento\Braintree\Test\Block\Adminhtml\Report\Grid" locator="//div[contains(@data-bind, 'braintree_report')]" strategy="xpath"/> </page> </config> -- GitLab From 6f24431ce01b0789dda3d6b08c1ebe06fa657e87 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 22 Aug 2016 17:28:12 +0300 Subject: [PATCH 562/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Category/Plugin/Storage.php | 2 +- .../Model/Category/Plugin/StorageTest.php | 39 ++++++++++++------- .../Cms/Model/ResourceModel/PageTest.php | 13 +------ .../Adminhtml/Product/Builder/Plugin.php | 13 +++---- ...torySave.php => ProductRepositorySave.php} | 6 ++- .../Model/Product/Validator/Plugin.php | 6 ++- .../Adminhtml/Product/Builder/PluginTest.php | 14 ++----- ...Test.php => ProductRepositorySaveTest.php} | 20 +++++----- .../Model/Product/Validator/PluginTest.php | 8 ++-- .../Option/Plugin/ConfigurableProductTest.php | 9 ++--- .../Magento/ConfigurableProduct/etc/di.xml | 2 +- .../Customer/Controller/Plugin/Account.php | 17 ++++---- .../Unit/Controller/Plugin/AccountTest.php | 19 ++++++--- .../Product/Quote/Plugin/InitializerTest.php | 26 ++++++------- .../Asset/Plugin/CleanMergedJsCssTest.php | 6 +-- .../Store/App/Action/Plugin/Context.php | 2 + .../Unit/App/Action/Plugin/ContextTest.php | 4 +- .../Unit/App/Action/Plugin/StoreCheckTest.php | 4 +- .../Unit/App/Action/ContextPluginTest.php | 6 +-- .../Quote/GrandTotalDetailsPluginTest.php | 2 +- .../Unit/Model/Url/Plugin/SignatureTest.php | 10 +++-- .../Unit/App/Action/ContextPluginTest.php | 8 ++-- 22 files changed, 119 insertions(+), 117 deletions(-) rename app/code/Magento/ConfigurableProduct/Model/Plugin/{AroundProductRepositorySave.php => ProductRepositorySave.php} (96%) rename app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/{AroundProductRepositorySaveTest.php => ProductRepositorySaveTest.php} (94%) diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php index d024a20e032..740c3276269 100644 --- a/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php +++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Storage.php @@ -33,7 +33,7 @@ class Storage /** * @param \Magento\UrlRewrite\Model\StorageInterface $object - * @param void $result + * @param null $result * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php index aa46787d009..d74e3c81e5c 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php @@ -3,13 +3,12 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\CatalogUrlRewrite\Model\Category\ProductFactory; use Magento\UrlRewrite\Model\StorageInterface; -use Magento\CatalogUrlRewrite\Model\Category\Plugin\Storage; +use Magento\CatalogUrlRewrite\Model\Category\Plugin\Storage as CategoryStoragePlugin; use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\CatalogUrlRewrite\Model\Category\Product; @@ -17,25 +16,39 @@ use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\Product as ProductRes class StorageTest extends \PHPUnit_Framework_TestCase { - /** @var Storage */ - private $model; + /** + * @var CategoryStoragePlugin + */ + private $plugin; - /** @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject */ + /** + * @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject + */ private $productFactory; - /** @var UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** + * @var UrlFinderInterface|\PHPUnit_Framework_MockObject_MockObject + */ private $urlFinder; - /** @var StorageInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** + * @var StorageInterface|\PHPUnit_Framework_MockObject_MockObject + */ private $storage; - /** @var Product|\PHPUnit_Framework_MockObject_MockObject */ + /** + * @var Product|\PHPUnit_Framework_MockObject_MockObject + */ private $product; - /** @var ProductResourceModel|\PHPUnit_Framework_MockObject_MockObject */ + /** + * @var ProductResourceModel|\PHPUnit_Framework_MockObject_MockObject + */ private $productResourceModel; - /** @var UrlRewrite|\PHPUnit_Framework_MockObject_MockObject */ + /** + * @var UrlRewrite|\PHPUnit_Framework_MockObject_MockObject + */ private $urlRewrite; protected function setUp() @@ -59,8 +72,8 @@ class StorageTest extends \PHPUnit_Framework_TestCase ->setMethods(['getMetadata', 'getEntityType', 'getIsAutogenerated', 'getUrlRewriteId', 'getEntityId']) ->getMock(); - $this->model = (new ObjectManager($this))->getObject( - Storage::class, + $this->plugin = (new ObjectManager($this))->getObject( + CategoryStoragePlugin::class, [ 'productFactory' => $this->productFactory, 'urlFinder' => $this->urlFinder @@ -85,6 +98,6 @@ class StorageTest extends \PHPUnit_Framework_TestCase $this->product->expects(static::once())->method('getResource')->willReturn($this->productResourceModel); $this->productResourceModel->expects(static::once())->method('saveMultiple')->willReturnSelf(); - $this->model->afterReplace($this->storage, null, $productUrls); + $this->plugin->afterReplace($this->storage, null, $productUrls); } } diff --git a/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php b/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php index 832314bd85f..277e36b94fc 100644 --- a/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php +++ b/app/code/Magento/CmsUrlRewrite/Test/Unit/Plugin/Cms/Model/ResourceModel/PageTest.php @@ -30,19 +30,10 @@ class PageTest extends \PHPUnit_Framework_TestCase */ protected $cmsPageResourceMock; - /** - * @var \Closure - */ - protected $closureMock; - protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->closureMock = function () { - return 'URL Rewrite Result'; - }; - $this->urlPersistMock = $this->getMockBuilder(\Magento\UrlRewrite\Model\UrlPersistInterface::class) ->getMockForAbstractClass(); @@ -62,7 +53,7 @@ class PageTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundDeletePositive() + public function testAfterDeletePositive() { $productId = 100; @@ -93,7 +84,7 @@ class PageTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundDeleteNegative() + public function testAfterDeleteNegative() { $this->cmsPageMock->expects($this->once()) ->method('isDeleted') diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php index a07f2532988..354ebdb0ea7 100644 --- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Builder/Plugin.php @@ -9,7 +9,7 @@ namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product\Builder; use Magento\Catalog\Model\ProductFactory; use Magento\ConfigurableProduct\Model\Product\Type; use Magento\Catalog\Model\Product; -use Magento\Catalog\Controller\Adminhtml\Product\Builder; +use Magento\Catalog\Controller\Adminhtml\Product\Builder as CatalogProductBuilder; use Magento\Framework\App\RequestInterface; class Plugin @@ -35,18 +35,17 @@ class Plugin } /** - * @param Builder $subject + * Set type and data to configurable product + * + * @param CatalogProductBuilder $subject * @param Product $product * @param RequestInterface $request * @return Product * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function afterBuild( - Builder $subject, - Product $product, - RequestInterface $request - ) { + public function afterBuild(CatalogProductBuilder $subject, Product $product, RequestInterface $request) + { if ($request->has('attributes')) { $attributes = $request->getParam('attributes'); if (!empty($attributes)) { diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php similarity index 96% rename from app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php rename to app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php index 0165ec8ac02..0c25b4633c4 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Plugin/AroundProductRepositorySave.php +++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php @@ -15,9 +15,9 @@ use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; /** - * Class AroundProductRepositorySave + * Class ProductRepositorySave */ -class AroundProductRepositorySave +class ProductRepositorySave { /** * @var ProductAttributeRepositoryInterface @@ -42,6 +42,8 @@ class AroundProductRepositorySave } /** + * Validate product links and reset configurable attributes to configurable product + * * @param ProductRepositoryInterface $subject * @param ProductInterface $result * @param ProductInterface $product diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php index 05659796b2f..b5970c90274 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Validator/Plugin.php @@ -48,6 +48,8 @@ class Plugin } /** + * Set configurable type to product + * * @param Product\Validator $subject * @param Product $product * @param RequestInterface $request @@ -58,7 +60,7 @@ class Plugin public function beforeValidate( \Magento\Catalog\Model\Product\Validator $subject, \Magento\Catalog\Model\Product $product, - \Magento\Framework\App\RequestInterface $request, + RequestInterface $request, DataObject $response ) { if ($request->has('attributes')) { @@ -81,7 +83,7 @@ class Plugin \Magento\Catalog\Model\Product\Validator $subject, $result, \Magento\Catalog\Model\Product $product, - \Magento\Framework\App\RequestInterface $request, + RequestInterface $request, DataObject $response ) { $variationProducts = (array)$request->getPost('variations-matrix'); diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php index 80a1bbd4ce6..bc4f156cd8f 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php @@ -52,11 +52,6 @@ class PluginTest extends \PHPUnit_Framework_TestCase */ protected $subjectMock; - /** - * @var \Closure - */ - protected $closureMock; - protected function setUp() { $this->productFactoryMock = $this->getMock( @@ -124,9 +119,6 @@ class PluginTest extends \PHPUnit_Framework_TestCase '', false ); - $this->closureMock = function () use ($product) { - return $product; - }; $this->plugin = new \Magento\ConfigurableProduct\Controller\Adminhtml\Product\Builder\Plugin( $this->productFactoryMock, $this->configurableTypeMock @@ -137,7 +129,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase * @return void * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testAroundBuild() + public function testAfterBuild() { $this->requestMock->expects($this->once())->method('has')->with('attributes')->will($this->returnValue(true)); $valueMap = [ @@ -260,7 +252,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundBuildWhenProductNotHaveAttributeAndRequiredParameters() + public function testAfterBuildWhenProductNotHaveAttributeAndRequiredParameters() { $valueMap = [ ['attributes', null, null], @@ -287,7 +279,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundBuildWhenAttributesAreEmpty() + public function testAfterBuildWhenAttributesAreEmpty() { $valueMap = [['popup', null, false], ['product', null, 'product'], ['id', false, false]]; $this->requestMock->expects($this->once())->method('has')->with('attributes')->will($this->returnValue(false)); diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php similarity index 94% rename from app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php rename to app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php index bb1c8908673..ce3323dae06 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php @@ -11,16 +11,16 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ProductFactory; use Magento\ConfigurableProduct\Api\Data\OptionInterface; -use Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave; +use Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** - * Class AroundProductRepositorySaveTest + * Class ProductRepositorySaveTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase +class ProductRepositorySaveTest extends \PHPUnit_Framework_TestCase { /** * @var ProductAttributeRepositoryInterface|MockObject @@ -63,7 +63,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase private $option; /** - * @var AroundProductRepositorySave + * @var ProductRepositorySave */ private $plugin; @@ -97,13 +97,13 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $this->option = $this->getMockForAbstractClass(OptionInterface::class); - $this->plugin = new AroundProductRepositorySave( + $this->plugin = new ProductRepositorySave( $this->productAttributeRepository, $this->productFactory ); } - public function testAroundSaveWhenProductIsSimple() + public function testAfterSaveWhenProductIsSimple() { $this->product->expects(static::once()) ->method('getTypeId') @@ -117,7 +117,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundSaveWithoutOptions() + public function testAfterSaveWithoutOptions() { $this->product->expects(static::once()) ->method('getTypeId') @@ -147,7 +147,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase * @expectedException \Magento\Framework\Exception\InputException * @expectedExceptionMessage Products "5" and "4" have the same set of attribute values. */ - public function testAroundSaveWithLinks() + public function testAfterSaveWithLinks() { $links = [4, 5]; $this->product->expects(static::once()) @@ -189,7 +189,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase * @expectedException \Magento\Framework\Exception\InputException * @expectedExceptionMessage Product with id "4" does not contain required attribute "color". */ - public function testAroundSaveWithLinksWithMissingAttribute() + public function testAfterSaveWithLinksWithMissingAttribute() { $simpleProductId = 4; $links = [$simpleProductId, 5]; @@ -246,7 +246,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase * @expectedException \Magento\Framework\Exception\InputException * @expectedExceptionMessage Products "5" and "4" have the same set of attribute values. */ - public function testAroundSaveWithLinksWithDuplicateAttributes() + public function testAfterSaveWithLinksWithDuplicateAttributes() { $links = [4, 5]; $attributeCode = 'color'; diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php index 466cc0266ad..65d3f42767d 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Validator/PluginTest.php @@ -119,7 +119,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundValidateWithVariationsValid() + public function testAfterValidateWithVariationsValid() { $matrix = ['products']; @@ -165,7 +165,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundValidateWithVariationsInvalid() + public function testAfterValidateWithVariationsInvalid() { $matrix = ['products']; @@ -212,7 +212,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundValidateIfVariationsNotExist() + public function testAfterValidateIfVariationsNotExist() { $this->requestMock->expects( $this->once() @@ -233,7 +233,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundValidateWithVariationsAndRequiredAttributes() + public function testAfterValidateWithVariationsAndRequiredAttributes() { $matrix = [ ['data1', 'data2', 'configurable_attribute' => ['data1']], diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php index 2ad52012afc..fb619395e7a 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php @@ -3,18 +3,15 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\ConfigurableProduct\Test\Unit\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin; class ConfigurableProductTest extends \PHPUnit_Framework_TestCase { /** * @param array $data - * @dataProvider aroundGetStockItemDataProvider + * @dataProvider afterGetStockItemDataProvider */ - public function testAroundGetStockItem(array $data) + public function testAfterGetStockItem(array $data) { $subjectMock = $this->getMock( \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class, @@ -49,7 +46,7 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase /** * @return array */ - public function aroundGetStockItemDataProvider() + public function afterGetStockItemDataProvider() { return [ [ diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index 8e793925e1c..5332c4fdf9b 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -59,7 +59,7 @@ </arguments> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="configurableProductSaveOptions" sortOrder="10" type="Magento\ConfigurableProduct\Model\Plugin\AroundProductRepositorySave"/> + <plugin name="configurableProductSaveOptions" sortOrder="1" type="\Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave"/> </type> <type name="Magento\Catalog\Model\Product"> <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" /> diff --git a/app/code/Magento/Customer/Controller/Plugin/Account.php b/app/code/Magento/Customer/Controller/Plugin/Account.php index b697a381961..5da79b8aa46 100644 --- a/app/code/Magento/Customer/Controller/Plugin/Account.php +++ b/app/code/Magento/Customer/Controller/Plugin/Account.php @@ -37,14 +37,14 @@ class Account } /** + * Dispatch actions allowed for not authorized users + * * @param AbstractAction $subject * @param RequestInterface $request * @return void */ - public function beforeDispatch( - AbstractAction $subject, - RequestInterface $request - ) { + public function beforeDispatch(AbstractAction $subject, RequestInterface $request) + { $action = strtolower($request->getActionName()); $pattern = '/^(' . implode('|', $this->allowedActions) . ')$/i'; @@ -58,7 +58,7 @@ class Account } /** - * Dispatch actions allowed for not authorized users + * Remove No-referer flag from customer session * * @param AbstractAction $subject * @param ResponseInterface|ResultInterface $result @@ -66,11 +66,8 @@ class Account * @return ResponseInterface|ResultInterface * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterDispatch( - AbstractAction $subject, - $result, - RequestInterface $request - ) { + public function afterDispatch(AbstractAction $subject, $result, RequestInterface $request) + { $this->session->unsNoReferer(false); return $result; } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php index 9bf7febe4e5..c1111bd8dea 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php @@ -12,6 +12,7 @@ use Magento\Framework\App\ActionInterface; use Magento\Framework\App\Action\AbstractAction; use Magento\Framework\App\Request\Http; use Magento\Framework\Controller\ResultInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class AccountTest extends \PHPUnit_Framework_TestCase { @@ -76,7 +77,6 @@ class AccountTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->resultInterface = $this->getMockBuilder(ResultInterface::class) - ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->actionFlag = $this->getMockBuilder(\Magento\Framework\App\ActionFlag::class) @@ -90,7 +90,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase * @param boolean $isActionAllowed * @param boolean $isAuthenticated * - * @dataProvider dataProviderBeforeDispatch + * @dataProvider beforeDispatchDataProvider */ public function testBeforeDispatch( $action, @@ -127,7 +127,10 @@ class AccountTest extends \PHPUnit_Framework_TestCase $plugin->beforeDispatch($this->subject, $this->request); } - public function dataProviderBeforeDispatch() + /** + * @return array + */ + public function beforeDispatchDataProvider() { return [ [ @@ -170,8 +173,14 @@ class AccountTest extends \PHPUnit_Framework_TestCase ->with(false) ->willReturnSelf(); - $plugin = new Account($this->session, ['testaction']); - $this->assertEquals( + $plugin = (new ObjectManager($this))->getObject( + Account::class, + [ + 'session' => $this->session, + ['testaction'] + ] + ); + $this->assertSame( $this->resultInterface, $plugin->afterDispatch($this->subject, $this->resultInterface, $this->request) ); diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php index 3c7c695379c..43d7aa93dd0 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/Sales/AdminOrder/Product/Quote/Plugin/InitializerTest.php @@ -5,11 +5,11 @@ */ namespace Magento\GroupedProduct\Test\Unit\Model\Sales\AdminOrder\Product\Quote\Plugin; -use Magento\GroupedProduct\Model\Sales\AdminOrder\Product\Quote\Plugin\Initializer as Model; -use Magento\Sales\Model\AdminOrder\Product\Quote\Initializer; +use Magento\GroupedProduct\Model\Sales\AdminOrder\Product\Quote\Plugin\Initializer as QuoteInitializerPlugin; +use Magento\Sales\Model\AdminOrder\Product\Quote\Initializer as QuoteInitializer; use Magento\Quote\Model\Quote; use Magento\Catalog\Model\Product; -use Magento\Quote\Model\Quote\Item; +use Magento\Quote\Model\Quote\Item as QuoteItem; use Magento\Framework\DataObject; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; @@ -21,12 +21,12 @@ class InitializerTest extends \PHPUnit_Framework_TestCase private $objectManagerHelper; /** - * @var Model|\PHPUnit_Framework_MockObject_MockObject + * @var QuoteInitializerPlugin|\PHPUnit_Framework_MockObject_MockObject */ - private $model; + private $plugin; /** - * @var Initializer|\PHPUnit_Framework_MockObject_MockObject + * @var QuoteInitializer|\PHPUnit_Framework_MockObject_MockObject */ private $initializer; @@ -36,7 +36,7 @@ class InitializerTest extends \PHPUnit_Framework_TestCase private $quote; /** - * @var Item|\PHPUnit_Framework_MockObject_MockObject + * @var QuoteItem|\PHPUnit_Framework_MockObject_MockObject */ private $quoteItem; @@ -54,7 +54,7 @@ class InitializerTest extends \PHPUnit_Framework_TestCase { $this->objectManagerHelper = new ObjectManagerHelper($this); - $this->initializer = $this->getMockBuilder(Initializer::class) + $this->initializer = $this->getMockBuilder(QuoteInitializer::class) ->disableOriginalConstructor() ->getMock(); $this->quote = $this->getMockBuilder(Quote::class) @@ -65,23 +65,23 @@ class InitializerTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['getTypeId']) ->getMock(); - $this->quoteItem = $this->getMockBuilder(Item::class) + $this->quoteItem = $this->getMockBuilder(QuoteItem::class) ->disableOriginalConstructor() ->getMock(); $this->config = $this->getMockBuilder(DataObject::class) ->disableOriginalConstructor() ->getMock(); - $this->model = $this->objectManagerHelper->getObject( - Model::class + $this->plugin = $this->objectManagerHelper->getObject( + QuoteInitializerPlugin::class ); } public function testAfterInit() { - $this->assertEquals( + $this->assertSame( $this->quoteItem, - $this->model->afterInit($this->initializer, $this->quoteItem, $this->quote, $this->product, $this->config) + $this->plugin->afterInit($this->initializer, $this->quoteItem, $this->quote, $this->product, $this->config) ); } } diff --git a/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php b/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php index c60af5f5667..9ff39118595 100644 --- a/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php +++ b/app/code/Magento/MediaStorage/Test/Unit/Model/Asset/Plugin/CleanMergedJsCssTest.php @@ -3,9 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\MediaStorage\Test\Unit\Model\Asset\Plugin; use Magento\Framework\App\Filesystem\DirectoryList; @@ -41,9 +38,8 @@ class CleanMergedJsCssTest extends \Magento\Framework\TestFramework\Unit\BaseTes ); } - public function testAroundCleanMergedJsCss() + public function testAfterCleanMergedJsCss() { - $this->hasBeenCalled = true; $readDir = 'read directory'; $mergedDir = $readDir . '/' . \Magento\Framework\View\Asset\Merged::getRelativeDir(); diff --git a/app/code/Magento/Store/App/Action/Plugin/Context.php b/app/code/Magento/Store/App/Action/Plugin/Context.php index 2ad390316b3..1b454538425 100644 --- a/app/code/Magento/Store/App/Action/Plugin/Context.php +++ b/app/code/Magento/Store/App/Action/Plugin/Context.php @@ -58,6 +58,8 @@ class Context } /** + * Set store and currency to http context + * * @param AbstractAction $subject * @param RequestInterface $request * @return void diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php index 2dd233182e5..2411475b203 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/ContextTest.php @@ -114,7 +114,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase '', false ); - $this->requestMock = $this->getMock(RequestInterface::class); + $this->requestMock = $this->getMockBuilder(RequestInterface::class)->getMockForAbstractClass(); $this->subjectMock = $this->getMockBuilder(AbstractAction::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -146,7 +146,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(self::CURRENCY_CURRENT_STORE)); } - public function testAroundDispatchCurrencyFromSession() + public function testBeforeDispatchCurrencyFromSession() { $this->storeMock->expects($this->once()) ->method('getDefaultCurrencyCode') diff --git a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php index 744ea82d2f1..7e443a05c1b 100644 --- a/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php +++ b/app/code/Magento/Store/Test/Unit/App/Action/Plugin/StoreCheckTest.php @@ -55,13 +55,13 @@ class StoreCheckTest extends \PHPUnit_Framework_TestCase * @expectedException \Magento\Framework\Exception\State\InitException * @expectedExceptionMessage Current store is not active. */ - public function testAroundDispatchWhenStoreNotActive() + public function testBeforeDispatchWhenStoreNotActive() { $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(false)); $this->_plugin->beforeDispatch($this->subjectMock, $this->requestMock); } - public function testAroundDispatchWhenStoreIsActive() + public function testBeforeDispatchWhenStoreIsActive() { $this->_storeMock->expects($this->any())->method('isActive')->will($this->returnValue(true)); $this->_plugin->beforeDispatch($this->subjectMock, $this->requestMock); diff --git a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php index 58b2b5e6d89..a95ead9efe3 100644 --- a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php @@ -111,9 +111,9 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase * @param bool $cache * @param bool $taxEnabled * @param bool $loggedIn - * @dataProvider dataProviderAroundDispatch + * @dataProvider beforeDispatchDataProvider */ - public function testAroundDispatch($cache, $taxEnabled, $loggedIn) + public function testBeforeDispatch($cache, $taxEnabled, $loggedIn) { $this->customerSessionMock->expects($this->any()) ->method('isLoggedIn') @@ -167,7 +167,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase /** * @return array */ - public function dataProviderAroundDispatch() + public function beforeDispatchDataProvider() { return [ [false, false, false], diff --git a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php index 82ce962daef..693b0d437af 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php @@ -148,7 +148,7 @@ class GrandTotalDetailsPluginTest extends \PHPUnit_Framework_TestCase return $taxDetailsMock; } - public function testAroundProcess() + public function testAfterProcess() { $taxRate = [ 'percent' => 8.25, diff --git a/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php b/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php index a55ea73aefc..58cf9bcc31e 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Url/Plugin/SignatureTest.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Theme\Test\Unit\Model\Url\Plugin; use \Magento\Theme\Model\Url\Plugin\Signature; @@ -41,9 +40,9 @@ class SignatureTest extends \PHPUnit_Framework_TestCase /** * @param bool|int $fixtureConfigFlag * @param string $inputUrlType - * @dataProvider aroundGetBaseUrlInactiveDataProvider + * @dataProvider afterGetBaseUrlInactiveDataProvider */ - public function testAroundGetBaseUrlInactive($fixtureConfigFlag, $inputUrlType) + public function testAfterGetBaseUrlInactive($fixtureConfigFlag, $inputUrlType) { $this->config ->expects($this->any()) @@ -57,7 +56,10 @@ class SignatureTest extends \PHPUnit_Framework_TestCase $this->assertEquals('http://127.0.0.1/magento/pub/static/', $actualResult); } - public function aroundGetBaseUrlInactiveDataProvider() + /** + * @return array + */ + public function afterGetBaseUrlInactiveDataProvider() { return [ 'disabled in config, relevant URL type' => [0, \Magento\Framework\UrlInterface::URL_TYPE_STATIC], diff --git a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php index 95694b9386d..77c8070ca44 100644 --- a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php @@ -123,7 +123,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase ); } - public function testAroundDispatchBasedOnDefault() + public function testBeforeDispatchBasedOnDefault() { $this->customerSessionMock->expects($this->once()) ->method('isLoggedIn') @@ -191,7 +191,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $this->contextPlugin->beforeDispatch($action, $request); } - public function testAroundDispatchBasedOnOrigin() + public function testBeforeDispatchBasedOnOrigin() { $this->customerSessionMock->expects($this->once()) ->method('isLoggedIn') @@ -220,7 +220,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $this->contextPlugin->beforeDispatch($action, $request); } - public function testAroundDispatchBasedOnBilling() + public function testBeforeDispatchBasedOnBilling() { $this->customerSessionMock->expects($this->once()) ->method('isLoggedIn') @@ -292,7 +292,7 @@ class ContextPluginTest extends \PHPUnit_Framework_TestCase $this->contextPlugin->beforeDispatch($action, $request); } - public function testAroundDispatchBasedOnShipping() + public function testBeforeDispatchBasedOnShipping() { $this->customerSessionMock->expects($this->once()) ->method('isLoggedIn') -- GitLab From 913e6f509015225b4041a1887f8d2305ad0f35e2 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 22 Aug 2016 17:32:10 +0300 Subject: [PATCH 563/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage - Changed sort order; --- app/code/Magento/ConfigurableProduct/etc/di.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index 5332c4fdf9b..f661709a735 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -59,7 +59,7 @@ </arguments> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="configurableProductSaveOptions" sortOrder="1" type="\Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave"/> + <plugin name="configurableProductSaveOptions" sortOrder="10" type="\Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave"/> </type> <type name="Magento\Catalog\Model\Product"> <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" /> -- GitLab From 7fee068ce376bd3ceccc18848e99fae8dce0aba3 Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Thu, 28 Jul 2016 16:34:55 +0300 Subject: [PATCH 564/838] MAGETWO-49545: [JS] Adding a Field Shortcut to Calculate Price using % - MAGETWO-55977: Integrate calculator to Advanced pricing on Product page --- .../Product/Form/Modifier/AdvancedPricing.php | 4 ++++ .../view/adminhtml/web/js/price-input.js | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 3b92e54355f..0417f629eeb 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -494,6 +494,7 @@ class AdvancedPricing extends AbstractModifier 'data' => [ 'config' => [ 'componentType' => Field::NAME, + 'component' => 'Magento_Catalog/js/price-input', 'formElement' => Input::NAME, 'dataType' => Price::NAME, 'label' => __('Price'), @@ -507,6 +508,9 @@ class AdvancedPricing extends AbstractModifier 'validate-greater-than-zero' => true, 'validate-number' => true, ], + 'imports' => [ + 'priceValue' => '${ $.provider }:data.product.price', + ], ], ], ], diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js new file mode 100644 index 00000000000..8c5692241a6 --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js @@ -0,0 +1,17 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'Magento_Ui/js/form/element/abstract' +], function (Abstract) { + 'use strict'; + + return Abstract.extend({ + defaults: { + priceValue: '', + showFallbackReset: false, + valueUpdate: 'afterkeydown' + } + }); +}); -- GitLab From 89adf8826473feb40b94fd67a8efd89a24f72f85 Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Thu, 28 Jul 2016 16:59:11 +0300 Subject: [PATCH 565/838] MAGETWO-49545: [JS] Adding a Field Shortcut to Calculate Price using % - MAGETWO-55977: Integrate calculator to Advanced pricing on Product page - Moved code from ce to ee --- .../Magento/Catalog/view/adminhtml/web/js/price-input.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js index 8c5692241a6..871896257ab 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js @@ -7,11 +7,5 @@ define([ ], function (Abstract) { 'use strict'; - return Abstract.extend({ - defaults: { - priceValue: '', - showFallbackReset: false, - valueUpdate: 'afterkeydown' - } - }); + return Abstract.extend({}); }); -- GitLab From d0f44f2de5e3ff9ce8d543af0bc8ff7761f8048b Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 11 Jul 2016 16:21:13 +0300 Subject: [PATCH 566/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55256: Schema upgrade --- .../Api/Data/ProductTierPriceInterface.php | 31 ++++++++++++++++++ .../Catalog/Model/Product/TierPrice.php | 32 +++++++++++++++++++ .../Magento/Catalog/Setup/UpgradeSchema.php | 26 +++++++++++++++ app/code/Magento/Catalog/etc/module.xml | 2 +- 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php index d5b354da1ea..6465458d7ca 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php @@ -18,8 +18,12 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface const VALUE = 'value'; + const PERCENTAGE_VALUE = 'percentage_value'; + const CUSTOMER_GROUP_ID = 'customer_group_id'; + const WEBSITE_ID = 'website_id'; + /** * Retrieve customer group id * @@ -65,6 +69,33 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface */ public function setValue($value); + /** + * Retrieve percentage value + * @return float + */ + public function getPercentageValue(); + + /** + * Set percentage value + * + * @param $value + * @return $this + */ + public function setPercentageValue($value); + + /** + * Retrieve website id + * @return int + */ + public function getWebsiteId(); + + /** + * Set website id + * @param int $websiteId + * @return $this + */ + public function setWebsiteId($websiteId); + /** * Retrieve existing extension attributes object. * diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 131280af1b1..0e18d59750f 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -55,6 +55,38 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme return $this->setData(self::VALUE, $value); } + /** + * @inheritdoc + */ + public function getPercentageValue() + { + return $this->getData(self::PERCENTAGE_VALUE); + } + + /** + * @inheritdoc + */ + public function setPercentageValue($value) + { + return $this->setData(self::PERCENTAGE_VALUE, $value); + } + + /** + * @inheritdoc + */ + public function setWebsiteId($websiteId) + { + return $this->setData(self::WEBSITE_ID, $websiteId); + } + + /** + * @inheritdoc + */ + public function getWebsiteId() + { + return $this->getData(self::WEBSITE_ID); + } + /** * Retrieve customer group id * diff --git a/app/code/Magento/Catalog/Setup/UpgradeSchema.php b/app/code/Magento/Catalog/Setup/UpgradeSchema.php index 03f3ac95817..616f1770beb 100644 --- a/app/code/Magento/Catalog/Setup/UpgradeSchema.php +++ b/app/code/Magento/Catalog/Setup/UpgradeSchema.php @@ -32,6 +32,10 @@ class UpgradeSchema implements UpgradeSchemaInterface if (version_compare($context->getVersion(), '2.0.6', '<')) { $this->addUniqueKeyToCategoryProductTable($setup); } + + if (version_compare($context->getVersion(), '2.1.0', '<')) { + $this->addPercentageValueColumn($setup); + } $setup->endSetup(); } @@ -278,4 +282,26 @@ class UpgradeSchema implements UpgradeSchemaInterface $connection->dropColumn($setup->getTable($filedInfo['table']), $filedInfo['column']); } } + + /** + * Add percentage value column + * @param SchemaSetupInterface $setup + * @return void + */ + private function addPercentageValueColumn(SchemaSetupInterface $setup) + { + $connection = $setup->getConnection(); + $connection->addColumn( + $setup->getTable('catalog_product_entity_tier_price'), + 'percentage_value', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, + 'nullable' => false, + 'default' => '0.00', + 'length' => '3,2', + 'comment' => 'Percentage value', + 'after' => 'value' + ] + ); + } } diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml index 87e82543fc6..1250b55b968 100644 --- a/app/code/Magento/Catalog/etc/module.xml +++ b/app/code/Magento/Catalog/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Catalog" setup_version="2.0.7"> + <module name="Magento_Catalog" setup_version="2.1.0"> <sequence> <module name="Magento_Eav"/> <module name="Magento_Cms"/> -- GitLab From 64ce943ea51a62c2eb54d7c211c783debb829a9e Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 11 Jul 2016 17:22:48 +0300 Subject: [PATCH 567/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55256: Schema upgrade --- app/code/Magento/Catalog/Setup/UpgradeSchema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Setup/UpgradeSchema.php b/app/code/Magento/Catalog/Setup/UpgradeSchema.php index 616f1770beb..8ae9bd5e9c3 100644 --- a/app/code/Magento/Catalog/Setup/UpgradeSchema.php +++ b/app/code/Magento/Catalog/Setup/UpgradeSchema.php @@ -298,7 +298,7 @@ class UpgradeSchema implements UpgradeSchemaInterface 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, 'nullable' => false, 'default' => '0.00', - 'length' => '3,2', + 'length' => '5,2', 'comment' => 'Percentage value', 'after' => 'value' ] -- GitLab From c95c26823a039dba4fa134f5e9c2d0a154d05a9b Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 12 Jul 2016 12:54:13 +0300 Subject: [PATCH 568/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55256: Schema upgrade --- .../Magento/Catalog/Api/ProductRepositoryInterfaceTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index f30c1bffa00..6436cd60273 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -888,11 +888,15 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup1, 'value' => 3.14, 'qty' => 5, + 'percentageValue' => 0, + 'websiteId' => 1, ], [ 'customer_group_id' => $custGroup2, 'value' => 3.45, 'qty' => 10, + 'percentageValue' => 0, + 'websiteId' => 1, ] ]; $this->saveProduct($productData); @@ -917,6 +921,8 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup3, 'value' => 2.10, 'qty' => 12, + 'percentageValue' => 0, + 'websiteId' => 1, ]; $response[self::KEY_TIER_PRICES] = $tierPrices; $response = $this->updateProduct($response); -- GitLab From 2f73c406ec37576a61712161b814195bf4813d33 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:44:32 +0300 Subject: [PATCH 569/838] MAGETWO-55261: Update Advanced Pricing Popup on product page - create product form modifier - create ui component --- .../Api/Data/ProductAttributeInterface.php | 4 ++- .../Config/Source/Product/Options/Price.php | 8 +++--- .../Source/ProductPriceOptionsInterface.php | 26 +++++++++++++++++++ app/code/Magento/Catalog/etc/di.xml | 1 + 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php diff --git a/app/code/Magento/Catalog/Api/Data/ProductAttributeInterface.php b/app/code/Magento/Catalog/Api/Data/ProductAttributeInterface.php index 4025b2accbb..804f06ff667 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductAttributeInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductAttributeInterface.php @@ -12,7 +12,6 @@ namespace Magento\Catalog\Api\Data; interface ProductAttributeInterface extends \Magento\Catalog\Api\Data\EavAttributeInterface { const ENTITY_TYPE_CODE = 'catalog_product'; - const CODE_TIER_PRICE_FIELD_PRICE = 'price'; const CODE_HAS_WEIGHT = 'product_has_weight'; const CODE_SPECIAL_PRICE = 'special_price'; const CODE_PRICE = 'price'; @@ -27,6 +26,9 @@ interface ProductAttributeInterface extends \Magento\Catalog\Api\Data\EavAttribu const CODE_COST = 'cost'; const CODE_SEO_FIELD_URL_KEY = 'url_key'; const CODE_TIER_PRICE = 'tier_price'; + const CODE_TIER_PRICE_FIELD_PRICE = 'price'; + const CODE_TIER_PRICE_FIELD_PERCENTAGE_VALUE = 'percentage_value'; + const CODE_TIER_PRICE_FIELD_VALUE_TYPE = 'value_type'; const CODE_SEO_FIELD_META_DESCRIPTION = 'meta_description'; const CODE_WEIGHT = 'weight'; } diff --git a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php index 9eb5e2e1fc7..67505401203 100644 --- a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php +++ b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php @@ -5,12 +5,14 @@ */ namespace Magento\Catalog\Model\Config\Source\Product\Options; +use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; + /** * Price types mode source * * @author Magento Core Team <core@magentocommerce.com> */ -class Price implements \Magento\Framework\Option\ArrayInterface +class Price implements ProductPriceOptionsInterface, \Magento\Framework\Option\ArrayInterface { /** * {@inheritdoc} @@ -20,8 +22,8 @@ class Price implements \Magento\Framework\Option\ArrayInterface public function toOptionArray() { return [ - ['value' => 'fixed', 'label' => __('Fixed')], - ['value' => 'percent', 'label' => __('Percent')] + ['value' => self::VALUE_FIXED, 'label' => __('Fixed')], + ['value' => self::VALUE_PERCENT, 'label' => __('Percent')], ]; } } diff --git a/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php b/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php new file mode 100644 index 00000000000..90fd2dd7a7e --- /dev/null +++ b/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php @@ -0,0 +1,26 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Model\Config\Source; + +/** + * Interface ProductPriceOptionsInterface + */ +interface ProductPriceOptionsInterface +{ + /**#@+ + * Values + */ + const VALUE_FIXED = 'fixed'; + const VALUE_PERCENT = 'percent'; + /**#@-*/ + + /** + * Return array of options as value-label pairs + * + * @return array Format: array(array('value' => '<value>', 'label' => '<label>'), ...) + */ + public function toOptionArray(); +} diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 36f072d3b0a..8163def574f 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -46,6 +46,7 @@ <preference for="Magento\Catalog\Api\AttributeSetFinderInterface" type="Magento\Catalog\Model\Product\Attribute\AttributeSetFinder" /> <preference for="Magento\Catalog\Api\CategoryListInterface" type="Magento\Catalog\Model\CategoryList" /> <preference for="Magento\Catalog\Api\Data\CategorySearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface" type="Magento\Catalog\Model\Config\Source\Product\Options\Price"/> <type name="Magento\Customer\Model\ResourceModel\Visitor"> <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" /> </type> -- GitLab From 3768c379845054fc367cb3e16c58a78da3440f7a Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:48:06 +0300 Subject: [PATCH 570/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../Api/Data/ProductTierPriceInterface.php | 31 -------- .../Backend/GroupPrice/AbstractGroupPrice.php | 74 ++++++++++++++----- .../Product/Attribute/Backend/Tierprice.php | 14 ++++ .../Catalog/Model/Product/TierPrice.php | 32 -------- .../Catalog/Model/Product/Type/Price.php | 30 +++++++- .../Backend/GroupPrice/AbstractGroupPrice.php | 26 ++++--- .../Product/Attribute/Backend/Tierprice.php | 1 + .../ResourceModel/Product/Collection.php | 46 +++--------- .../Catalog/etc/extension_attributes.xml | 9 ++- .../Api/ProductRepositoryInterfaceTest.php | 6 -- 10 files changed, 128 insertions(+), 141 deletions(-) diff --git a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php index 6465458d7ca..d5b354da1ea 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php @@ -18,12 +18,8 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface const VALUE = 'value'; - const PERCENTAGE_VALUE = 'percentage_value'; - const CUSTOMER_GROUP_ID = 'customer_group_id'; - const WEBSITE_ID = 'website_id'; - /** * Retrieve customer group id * @@ -69,33 +65,6 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface */ public function setValue($value); - /** - * Retrieve percentage value - * @return float - */ - public function getPercentageValue(); - - /** - * Set percentage value - * - * @param $value - * @return $this - */ - public function setPercentageValue($value); - - /** - * Retrieve website id - * @return int - */ - public function getWebsiteId(); - - /** - * Set website id - * @param int $websiteId - * @return $this - */ - public function setWebsiteId($websiteId); - /** * Retrieve existing extension attributes object. * diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index d104dc2ab68..e7b242aea40 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -270,37 +270,64 @@ abstract class AbstractGroupPrice extends Price */ public function afterLoad($object) { - $storeId = $object->getStoreId(); + $data = $this->_getResource()->loadPriceData( + $object->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()), + $this->getWebsiteId($object->getStoreId()) + ); + $this->setPriceData($object, $data); + + return $this; + } + + /** + * @param int $storeId + * @return int|null + */ + private function getWebsiteId($storeId) + { $websiteId = null; if ($this->getAttribute()->isScopeGlobal()) { $websiteId = 0; } elseif ($storeId) { $websiteId = $this->_storeManager->getStore($storeId)->getWebsiteId(); } + return $websiteId; + } - $data = $this->_getResource()->loadPriceData( - $object->getData($this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField()), - $websiteId - ); - foreach ($data as $k => $v) { - $data[$k]['website_price'] = $v['price']; - if ($v['all_groups']) { - $data[$k]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId(); - } - } - + /** + * @param \Magento\Catalog\Model\Product $object + * @param array $priceData + */ + public function setPriceData($object, $priceData) + { + $priceData = $this->modifyPriceData($object, $priceData); + $websiteId = $this->getWebsiteId($object->getStoreId()); if (!$object->getData('_edit_mode') && $websiteId) { - $data = $this->preparePriceData($data, $object->getTypeId(), $websiteId); + $priceData = $this->preparePriceData($priceData, $object->getTypeId(), $websiteId); } - $object->setData($this->getAttribute()->getName(), $data); - $object->setOrigData($this->getAttribute()->getName(), $data); + $object->setData($this->getAttribute()->getName(), $priceData); + $object->setOrigData($this->getAttribute()->getName(), $priceData); $valueChangedKey = $this->getAttribute()->getName() . '_changed'; $object->setOrigData($valueChangedKey, 0); $object->setData($valueChangedKey, 0); + } - return $this; + /** + * @param \Magento\Catalog\Model\Product $object + * @param array $data + * @return array + */ + protected function modifyPriceData($object, $data) + { + foreach ($data as $k => $v) { + $data[$k]['website_price'] = $v['price']; + if ($v['all_groups']) { + $data[$k]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId(); + } + } + return $data; } /** @@ -372,13 +399,14 @@ abstract class AbstractGroupPrice extends Price $useForAllGroups = $data['cust_group'] == $this->_groupManagement->getAllCustomersGroup()->getId(); $customerGroupId = !$useForAllGroups ? $data['cust_group'] : 0; - + $isPercentageValue = isset($data['percentage_value']) && $data['percentage_value'] > 0; $new[$key] = array_merge( [ 'website_id' => $data['website_id'], 'all_groups' => $useForAllGroups ? 1 : 0, 'customer_group_id' => $customerGroupId, - 'value' => $data['price'], + 'value' => $isPercentageValue ? 0 : $data['price'], + 'percentage_value' => $isPercentageValue ? $data['percentage_value'] : 0, ], $this->_getAdditionalUniqueFields($data) ); @@ -413,8 +441,14 @@ abstract class AbstractGroupPrice extends Price if (!empty($update)) { foreach ($update as $k => $v) { - if ($old[$k]['price'] != $v['value']) { - $price = new \Magento\Framework\DataObject(['value_id' => $old[$k]['price_id'], 'value' => $v['value']]); + if ($old[$k]['price'] != $v['value'] || $old[$k]['percentage_value'] != $v['percentage_value']) { + $price = new \Magento\Framework\DataObject( + [ + 'value_id' => $old[$k]['price_id'], + 'value' => $v['value'], + 'percentage_value' => $v['percentage_value'] + ] + ); $this->_getResource()->savePriceData($price); $isChanged = true; 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 fc0fc07d4d5..b1e763900b8 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -105,4 +105,18 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr { return false; } + + /** + * @inheritdoc + */ + protected function modifyPriceData($object, $data) + { + foreach ($data as $key => $tierPrice) { + if ($tierPrice['percentage_value'] > 0) { + $data[$key]['price'] = $object->getPrice() * (1 - $tierPrice['percentage_value'] / 100); + } + } + + return parent::modifyPriceData($object, $data); + } } diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 0e18d59750f..131280af1b1 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -55,38 +55,6 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme return $this->setData(self::VALUE, $value); } - /** - * @inheritdoc - */ - public function getPercentageValue() - { - return $this->getData(self::PERCENTAGE_VALUE); - } - - /** - * @inheritdoc - */ - public function setPercentageValue($value) - { - return $this->setData(self::PERCENTAGE_VALUE, $value); - } - - /** - * @inheritdoc - */ - public function setWebsiteId($websiteId) - { - return $this->setData(self::WEBSITE_ID, $websiteId); - } - - /** - * @inheritdoc - */ - public function getWebsiteId() - { - return $this->getData(self::WEBSITE_ID); - } - /** * Retrieve customer group id * diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index 20d25b9e5af..a43d811044d 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -10,6 +10,7 @@ use Magento\Catalog\Model\Product; use Magento\Customer\Api\GroupManagementInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Store\Model\Store; +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; /** * Product type price model @@ -80,6 +81,11 @@ class Price */ protected $config; + /** + * @var ProductTierPriceExtensionFactory + */ + private $tierPriceExtensionFactory; + /** * Price constructor. * @param \Magento\CatalogRule\Model\ResourceModel\RuleFactory $ruleFactory @@ -363,11 +369,29 @@ class Price } $tierPrice->setValue($value); $tierPrice->setQty($price['price_qty']); + if (!$tierPrice->getExtensionAttributes()) { + $tierPrice->setExtensionAttributes($this->getTierPriceExtensionAttributes()); + } + $tierPrice->getExtensionAttributes()->setPercentageValue($price['percentage_value']); + $tierPrice->getExtensionAttributes()->setWebsiteId($price['website_id']); $prices[] = $tierPrice; } return $prices; } + /** + * @deprecated + * @return \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface + */ + private function getTierPriceExtensionAttributes() + { + if (!$this->tierPriceExtensionFactory) { + $this->tierPriceExtensionFactory = \Magento\Framework\App\ObjectManager::getInstance() + ->get(ProductTierPriceExtensionFactory::class); + } + return $this->tierPriceExtensionFactory->create(); + } + /** * Sets list of product tier prices * @@ -382,19 +406,19 @@ class Price return $this; } - $websiteId = $this->getWebsiteForPriceScope(); $allGroupsId = $this->getAllCustomerGroupsId(); // build the new array of tier prices $prices = []; foreach ($tierPrices as $price) { $prices[] = [ - 'website_id' => $websiteId, + 'website_id' => $price->getExtensionAttributes()->getWebsiteId(), 'cust_group' => $price->getCustomerGroupId(), 'website_price' => $price->getValue(), 'price' => $price->getValue(), 'all_groups' => ($price->getCustomerGroupId() == $allGroupsId), - 'price_qty' => $price->getQty() + 'price_qty' => $price->getQty(), + 'percentage_value' => $price->getExtensionAttributes()->getPercentageValue() ]; } $product->setData('tier_price', $prices); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index 677d048de6a..717056ddde0 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -22,8 +22,21 @@ abstract class AbstractGroupPrice extends \Magento\Framework\Model\ResourceModel */ public function loadPriceData($productId, $websiteId = null) { - $connection = $this->getConnection(); + $select = $this->getSelect($websiteId); + $productIdFieldName = $this->getProductIdFieldName(); + $select->where("{$productIdFieldName} = ?", $productId); + + $this->_loadPriceDataSelect($select); + return $this->getConnection()->fetchAll($select); + } + + /** + * @param int|null $websiteId + * @return \Magento\Framework\DB\Select + */ + public function getSelect($websiteId = null) + { $columns = [ 'price_id' => $this->getIdFieldName(), 'website_id' => 'website_id', @@ -34,12 +47,8 @@ abstract class AbstractGroupPrice extends \Magento\Framework\Model\ResourceModel $columns = $this->_loadPriceDataColumns($columns); - $productIdFieldName = $this->getProductIdFieldName(); - $select = $connection->select() - ->from($this->getMainTable(), $columns) - ->where("{$productIdFieldName} = ?", $productId); - - $this->_loadPriceDataSelect($select); + $select = $this->getConnection()->select() + ->from($this->getMainTable(), $columns); if ($websiteId !== null) { if ($websiteId == '0') { @@ -48,8 +57,7 @@ abstract class AbstractGroupPrice extends \Magento\Framework\Model\ResourceModel $select->where('website_id IN(?)', [0, $websiteId]); } } - - return $connection->fetchAll($select); + return $select; } /** diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Tierprice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Tierprice.php index e75442637b9..0f17ecbf98e 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Backend/Tierprice.php @@ -34,6 +34,7 @@ class Tierprice extends AbstractGroupPrice { $columns = parent::_loadPriceDataColumns($columns); $columns['price_qty'] = 'qty'; + $columns['percentage_value'] = 'percentage_value'; return $columns; } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index f53c1b29f8b..19077872f1d 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -2103,57 +2103,29 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ $attribute = $this->getAttribute('tier_price'); + /* @var $backend \Magento\Catalog\Model\Product\Attribute\Backend\Tierprice */ + $backend = $attribute->getBackend(); $websiteId = 0; if (!$attribute->isScopeGlobal() && null !== $this->getStoreId()) { $websiteId = $this->_storeManager->getStore($this->getStoreId())->getWebsiteId(); } $linkField = $this->getConnection()->getAutoIncrementField($this->getTable('catalog_product_entity')); - $connection = $this->getConnection(); - $columns = [ - 'price_id' => 'value_id', - 'website_id' => 'website_id', - 'all_groups' => 'all_groups', - 'cust_group' => 'customer_group_id', - 'price_qty' => 'qty', - 'price' => 'value', - 'product_id' => $linkField, - ]; - $select = $connection->select()->from( - $this->getTable('catalog_product_entity_tier_price'), - $columns - )->where( + + $select = $backend->getResource()->getSelect($websiteId); + $select->columns(['product_id' => $linkField])->where( $linkField .' IN(?)', $productIds )->order( - [$linkField, 'qty'] + $linkField ); - if ($websiteId == 0) { - $select->where('website_id = ?', $websiteId); - } else { - $select->where('website_id IN(?)', [0, $websiteId]); - } - - foreach ($connection->fetchAll($select) as $row) { - $tierPrices[$row['product_id']][] = [ - 'website_id' => $row['website_id'], - 'cust_group' => $row['all_groups'] ? $this->_groupManagement->getAllCustomersGroup()->getId() : $row['cust_group'], - 'price_qty' => $row['price_qty'], - 'price' => $row['price'], - 'website_price' => $row['price'], - ]; + foreach ($this->getConnection()->fetchAll($select) as $row) { + $tierPrices[$row['product_id']][] = $row; } - /* @var $backend \Magento\Catalog\Model\Product\Attribute\Backend\Tierprice */ - $backend = $attribute->getBackend(); - foreach ($this->getItems() as $item) { - $data = $tierPrices[$item->getId()]; - if (!empty($data) && $websiteId) { - $data = $backend->preparePriceData($data, $item->getTypeId(), $websiteId); - } - $item->setData('tier_price', $data); + $backend->setPriceData($item, $tierPrices[$item->getId()]); } $this->setFlag('tier_price_added', true); diff --git a/app/code/Magento/Catalog/etc/extension_attributes.xml b/app/code/Magento/Catalog/etc/extension_attributes.xml index 976031cb937..e333c13bcc6 100644 --- a/app/code/Magento/Catalog/etc/extension_attributes.xml +++ b/app/code/Magento/Catalog/etc/extension_attributes.xml @@ -13,9 +13,6 @@ <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface"> <attribute code="website_ids" type="int[]"/> </extension_attributes> - <extension_attributes for="Magento\Catalog\Api\Data\ProductOptionInterface"> - <attribute code="custom_options" type="Magento\Catalog\Api\Data\CustomOptionInterface[]" /> - </extension_attributes> <extension_attributes for="Magento\Catalog\Api\Data\CustomOptionInterface"> <attribute code="file_info" type="Magento\Framework\Api\Data\ImageContentInterface"/> </extension_attributes> @@ -25,4 +22,10 @@ <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface"> <attribute code="category_links" type="Magento\Catalog\Api\Data\CategoryLinkInterface[]" /> </extension_attributes> + <extension_attributes for="Magento\Catalog\Api\Data\ProductTierPriceInterface"> + <attribute code="percentage_value" type="float" /> + </extension_attributes> + <extension_attributes for="Magento\Catalog\Api\Data\ProductTierPriceInterface"> + <attribute code="website_id" type="int" /> + </extension_attributes> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 6436cd60273..f30c1bffa00 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -888,15 +888,11 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup1, 'value' => 3.14, 'qty' => 5, - 'percentageValue' => 0, - 'websiteId' => 1, ], [ 'customer_group_id' => $custGroup2, 'value' => 3.45, 'qty' => 10, - 'percentageValue' => 0, - 'websiteId' => 1, ] ]; $this->saveProduct($productData); @@ -921,8 +917,6 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup3, 'value' => 2.10, 'qty' => 12, - 'percentageValue' => 0, - 'websiteId' => 1, ]; $response[self::KEY_TIER_PRICES] = $tierPrices; $response = $this->updateProduct($response); -- GitLab From d385ddbc85c183c898f2e2668cc700418442a236 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 15 Jul 2016 12:58:42 +0300 Subject: [PATCH 571/838] MAGETWO-55261: Update Advanced Pricing Popup on product page - fixes after CR --- .../Model/Config/Source/Product/Options/Price.php | 2 +- .../Config/Source/ProductPriceOptionsInterface.php | 11 +++-------- .../Product/Form/Modifier/AdvancedPricing.php | 5 +++++ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php index 67505401203..b994c787bee 100644 --- a/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php +++ b/app/code/Magento/Catalog/Model/Config/Source/Product/Options/Price.php @@ -12,7 +12,7 @@ use Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface; * * @author Magento Core Team <core@magentocommerce.com> */ -class Price implements ProductPriceOptionsInterface, \Magento\Framework\Option\ArrayInterface +class Price implements ProductPriceOptionsInterface { /** * {@inheritdoc} diff --git a/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php b/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php index 90fd2dd7a7e..d5d5062bad7 100644 --- a/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php +++ b/app/code/Magento/Catalog/Model/Config/Source/ProductPriceOptionsInterface.php @@ -5,10 +5,12 @@ */ namespace Magento\Catalog\Model\Config\Source; +use Magento\Framework\Data\OptionSourceInterface; + /** * Interface ProductPriceOptionsInterface */ -interface ProductPriceOptionsInterface +interface ProductPriceOptionsInterface extends OptionSourceInterface { /**#@+ * Values @@ -16,11 +18,4 @@ interface ProductPriceOptionsInterface const VALUE_FIXED = 'fixed'; const VALUE_PERCENT = 'percent'; /**#@-*/ - - /** - * Return array of options as value-label pairs - * - * @return array Format: array(array('value' => '<value>', 'label' => '<label>'), ...) - */ - public function toOptionArray(); } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 0417f629eeb..13a99f9e98c 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -452,6 +452,7 @@ class AdvancedPricing extends AbstractModifier 'value' => $this->getDefaultWebsite(), 'visible' => $this->isMultiWebsites(), 'disabled' => ($this->isShowWebsiteColumn() && !$this->isAllowChangeWebsite()), + 'sortOrder' => 10, ], ], ], @@ -467,6 +468,7 @@ class AdvancedPricing extends AbstractModifier 'label' => __('Customer Group'), 'options' => $this->getCustomerGroups(), 'value' => $this->getDefaultCustomerGroup(), + 'sortOrder' => 20, ], ], ], @@ -480,6 +482,7 @@ class AdvancedPricing extends AbstractModifier 'dataType' => Number::NAME, 'label' => __('Quantity'), 'dataScope' => 'price_qty', + 'sortOrder' => 30, 'validation' => [ 'required-entry' => true, 'validate-greater-than-zero' => true, @@ -503,6 +506,7 @@ class AdvancedPricing extends AbstractModifier 'addbefore' => $this->locator->getStore() ->getBaseCurrency() ->getCurrencySymbol(), + 'sortOrder' => 40, 'validation' => [ 'required-entry' => true, 'validate-greater-than-zero' => true, @@ -522,6 +526,7 @@ class AdvancedPricing extends AbstractModifier 'componentType' => 'actionDelete', 'dataType' => Text::NAME, 'label' => '', + 'sortOrder' => 50, ], ], ], -- GitLab From cd7b0aaea626490c8695a273c6f0ef4b600102fb Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Fri, 15 Jul 2016 13:23:08 +0300 Subject: [PATCH 572/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../Product/Attribute/Backend/Tierprice.php | 21 +++++++ .../Catalog/Model/Product/Type/Price.php | 12 ++-- .../Unit/Model/Product/Type/PriceTest.php | 18 ++++++ .../Attribute/Backend/TierpriceTest.php | 15 +++++ .../Magento/Catalog/_files/product_simple.php | 55 +++++++++++-------- 5 files changed, 95 insertions(+), 26 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 b1e763900b8..a8733a0730a 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -119,4 +119,25 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr return parent::modifyPriceData($object, $data); } + + /** + * @inheritdoc + */ + public function validate($object) + { + $attribute = $this->getAttribute(); + $priceRows = $object->getData($attribute->getName()); + $priceRows = array_filter((array)$priceRows); + + foreach ($priceRows as $priceRow) { + $percentage = isset($priceRow['percentage_value']) ? $priceRow['percentage_value'] : 0 ; + if (!is_numeric($percentage) || $percentage < 0 || $percentage > 100) { + throw new \Magento\Framework\Exception\LocalizedException( + __('Percentage value must be a number between 0 and 100.') + ); + } + } + + return parent::validate($object); + } } diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index a43d811044d..4ce3c47e231 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -372,8 +372,10 @@ class Price if (!$tierPrice->getExtensionAttributes()) { $tierPrice->setExtensionAttributes($this->getTierPriceExtensionAttributes()); } - $tierPrice->getExtensionAttributes()->setPercentageValue($price['percentage_value']); - $tierPrice->getExtensionAttributes()->setWebsiteId($price['website_id']); + $percentageValue = isset($price['percentage_value']) ? $price['percentage_value'] : 0; + $websiteId = isset($price['website_id']) ? $price['website_id'] : $this->getWebsiteForPriceScope(); + $tierPrice->getExtensionAttributes()->setPercentageValue($percentageValue); + $tierPrice->getExtensionAttributes()->setWebsiteId($websiteId); $prices[] = $tierPrice; } return $prices; @@ -407,18 +409,20 @@ class Price } $allGroupsId = $this->getAllCustomerGroupsId(); + $websiteId = $this->getWebsiteForPriceScope(); // build the new array of tier prices $prices = []; foreach ($tierPrices as $price) { + $extensionAttributes = $price->getExtensionAttributes(); $prices[] = [ - 'website_id' => $price->getExtensionAttributes()->getWebsiteId(), + 'website_id' => $extensionAttributes ? $extensionAttributes->getWebsiteId() : $websiteId, 'cust_group' => $price->getCustomerGroupId(), 'website_price' => $price->getValue(), 'price' => $price->getValue(), 'all_groups' => ($price->getCustomerGroupId() == $allGroupsId), 'price_qty' => $price->getQty(), - 'percentage_value' => $price->getExtensionAttributes()->getPercentageValue() + 'percentage_value' => $extensionAttributes ? $extensionAttributes->getPercentageValue() : 0 ]; } $product->setData('tier_price', $prices); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index c51f9486c2e..04b39003f72 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -8,6 +8,8 @@ namespace Magento\Catalog\Test\Unit\Model\Product\Type; +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Customer\Model\GroupManagement; @@ -213,11 +215,27 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->assertEquals($tps[$i]->getQty(), $tpData['price_qty'], 'Qty does not match'); } + $tierPriceExtention = $this->getMockBuilder(ProductTierPriceExtensionInterface::class) + ->setMethods(['setWebsiteId', 'setPercentageValue', 'getPercentageValue']) + ->disableOriginalConstructor()->getMock(); + $tierPriceExtention->expects($this->any())->method('getPercentageValue')->willReturn(50); + $factoryMock = $this->getMockBuilder(ProductTierPriceExtensionFactory::class)->setMethods(['create']) + ->disableOriginalConstructor()->getMock(); + $factoryMock->expects($this->any())->method('create')->willReturn($tierPriceExtention); + + $reflection = new \ReflectionClass(get_class($this->model)); + $reflectionProperty = $reflection->getProperty('tierPriceExtensionFactory'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->model, $factoryMock); + // test with the data retrieved as a REST object $tpRests = $this->model->getTierPrices($this->product); $this->assertNotNull($tpRests); $this->assertTrue(is_array($tpRests)); $this->assertEquals(sizeof($tps), sizeof($tpRests)); + foreach ($tpRests as $tpRest) { + $this->assertEquals(50, $tpRest->getExtensionAttributes()->getPercentageValue()); + } for ($i = 0; $i < sizeof($tps); $i++) { $this->assertEquals( diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php index c69bdc1738b..e3117a37510 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php @@ -95,6 +95,21 @@ class TierpriceTest extends \PHPUnit_Framework_TestCase $this->_model->validate($product); } + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testValidatePercentage() + { + $product = new \Magento\Framework\DataObject(); + $product->setTierPrice( + [ + ['website_id' => 0, 'cust_group' => 1, 'price_qty' => 2, 'percentage_value' => 101], + ] + ); + + $this->_model->validate($product); + } + public function testPreparePriceData() { $data = [ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 794a2f9087a..2ddad36fac1 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -12,6 +12,38 @@ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); /** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */ $categoryLinkManagement = $objectManager->create(\Magento\Catalog\Api\CategoryLinkManagementInterface::class); +$tierPrices = []; +/** @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory */ +$tierPriceFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 2, + 'value' => 8 + ] + ] +); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 5, + 'value' => 5 + ] + ] +); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, + 'qty' => 3, + 'value' => 0, + 'percentage_value' => 50 + ] + ] +); + /** @var $product \Magento\Catalog\Model\Product */ $product = $objectManager->create(\Magento\Catalog\Model\Product::class); $product->isObjectNew(true); @@ -25,28 +57,7 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) ->setWeight(1) ->setShortDescription("Short description") ->setTaxClassId(0) - ->setTierPrice( - [ - [ - 'website_id' => 0, - 'cust_group' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, - 'price_qty' => 2, - 'price' => 8, - ], - [ - 'website_id' => 0, - 'cust_group' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, - 'price_qty' => 5, - 'price' => 5, - ], - [ - 'website_id' => 0, - 'cust_group' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, - 'price_qty' => 3, - 'price' => 5, - ], - ] - ) + ->setTierPrices($tierPrices) ->setDescription('Description with <b>html tag</b>') ->setMetaTitle('meta title') ->setMetaKeyword('meta keyword') -- GitLab From 7cf34d803569d63d7f9dbcbc10988fc20f133a0a Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Fri, 15 Jul 2016 14:04:32 +0300 Subject: [PATCH 573/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../Catalog/Api/ProductTierPriceManagementTest.php | 2 +- .../Magento/Catalog/_files/product_simple.php | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php index b1a1e7a3685..ff796829287 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php @@ -51,7 +51,7 @@ class ProductTierPriceManagementTest extends WebapiAbstract public function getListDataProvider() { return [ - [0, 1, 5, 3], + [0, 2, 5, 3], [1, 0, null, null], ['all', 2, 8, 2], ]; diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 2ddad36fac1..6f84bed99c3 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -38,7 +38,15 @@ $tierPrices[] = $tierPriceFactory->create( 'data' => [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 3, - 'value' => 0, + 'value' => 5 + ] + ] +); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, + 'qty' => 10, 'percentage_value' => 50 ] ] -- GitLab From a5b0ea1bb3f778e1982c915236eff99539a0de3f Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:49:28 +0300 Subject: [PATCH 574/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../ResourceModel/Product/Collection.php | 9 ++++--- .../Model/Import/AdvancedPricingTest.php | 12 ++++++++-- .../Attribute/Backend/TierpriceTest.php | 2 +- .../ResourceModel/Product/CollectionTest.php | 24 +++++++++++++++++++ .../ResourceModel/_files/product_simple.php | 7 +++++- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 19077872f1d..b2b20b9d223 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -2090,12 +2090,13 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac if ($this->getFlag('tier_price_added')) { return $this; } + $linkField = $this->getConnection()->getAutoIncrementField($this->getTable('catalog_product_entity')); $tierPrices = []; $productIds = []; foreach ($this->getItems() as $item) { - $productIds[] = $item->getId(); - $tierPrices[$item->getId()] = []; + $productIds[] = $item->getData($linkField); + $tierPrices[$item->getData($linkField)] = []; } if (!$productIds) { return $this; @@ -2110,8 +2111,6 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac $websiteId = $this->_storeManager->getStore($this->getStoreId())->getWebsiteId(); } - $linkField = $this->getConnection()->getAutoIncrementField($this->getTable('catalog_product_entity')); - $select = $backend->getResource()->getSelect($websiteId); $select->columns(['product_id' => $linkField])->where( $linkField .' IN(?)', @@ -2125,7 +2124,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac } foreach ($this->getItems() as $item) { - $backend->setPriceData($item, $tierPrices[$item->getId()]); + $backend->setPriceData($item, $tierPrices[$item->getData($linkField)]); } $this->setFlag('tier_price_added', true); diff --git a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php index e32939b195b..e5fd4cc0d96 100644 --- a/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php +++ b/dev/tests/integration/testsuite/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricingTest.php @@ -124,7 +124,11 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase $this->assertEquals(3, count($tierPriceCollection)); /** @var \Magento\Catalog\Model\Product\TierPrice $tierPrice */ foreach ($tierPriceCollection as $tierPrice) { - $this->assertContains($tierPrice->getData(), $this->expectedTierPrice[$sku]); + $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getPercentageValue()); + $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getWebsiteId()); + $tierPriceData = $tierPrice->getData(); + unset($tierPriceData['extension_attributes']); + $this->assertContains($tierPriceData, $this->expectedTierPrice[$sku]); } } } @@ -240,7 +244,11 @@ class AdvancedPricingTest extends \PHPUnit_Framework_TestCase $this->assertEquals(3, count($tierPriceCollection)); /** @var \Magento\Catalog\Model\Product\TierPrice $tierPrice */ foreach ($tierPriceCollection as $tierPrice) { - $this->assertContains($tierPrice->getData(), $this->expectedTierPrice[$sku]); + $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getPercentageValue()); + $this->assertEquals(0, $tierPrice->getExtensionAttributes()->getWebsiteId()); + $tierPriceData = $tierPrice->getData(); + unset($tierPriceData['extension_attributes']); + $this->assertContains($tierPriceData, $this->expectedTierPrice[$sku]); } } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php index e3117a37510..89dd932f8a0 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/TierpriceTest.php @@ -137,7 +137,7 @@ class TierpriceTest extends \PHPUnit_Framework_TestCase $this->_model->afterLoad($product); $price = $product->getTierPrice(); $this->assertNotEmpty($price); - $this->assertEquals(3, count($price)); + $this->assertEquals(4, count($price)); } /** diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php index f0a665d8be8..0d4a2c7363a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php @@ -17,6 +17,11 @@ class CollectionTest extends \PHPUnit_Framework_TestCase */ protected $processor; + /** + * @var \Magento\Catalog\Api\ProductRepositoryInterface + */ + private $productRepository; + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -30,6 +35,10 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $this->processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Catalog\Model\Indexer\Product\Price\Processor::class ); + + $this->productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + 'Magento\Catalog\Api\ProductRepositoryInterface' + ); } /** @@ -100,4 +109,19 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $this->assertCount(2, $items); $this->assertEquals(15, $product->getPrice()); } + + /** + * @magentoDataFixture Magento/Catalog/Model/ResourceModel/_files/product_simple.php + * @magentoDbIsolation enabled + */ + public function testGetProductsWithTierPrice() + { + $product = $this->productRepository->get('simple products'); + $items = $this->collection->addIdFilter($product->getId())->addAttributeToSelect('price') + ->load()->addTierPriceData(); + $tierPrices = $items->getFirstItem()->getTierPrices(); + $this->assertCount(3, $tierPrices); + $this->assertEquals(50, $tierPrices[2]->getExtensionAttributes()->getPercentageValue()); + $this->assertEquals(5, $tierPrices[2]->getValue()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/product_simple.php index 60e5ad4f8b7..c1a7ef37dac 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/_files/product_simple.php @@ -10,7 +10,6 @@ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\Product::class); $product->isObjectNew(true); $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) - ->setId(2) ->setAttributeSetId(4) ->setWebsiteIds([1]) ->setName('Simple Products') @@ -33,6 +32,12 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) 'price_qty' => 21, 'price' => 81, ], + [ + 'website_id' => 0, + 'cust_group' => Group::CUST_GROUP_ALL, + 'price_qty' => 30, + 'percentage_value' => 50, + ], ] ) ->setDescription('Description with <b>html tag</b>') -- GitLab From be19feea5b76390a71f23cd98f5da5041c54098f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Mon, 18 Jul 2016 15:43:44 +0300 Subject: [PATCH 575/838] MAGETWO-49543: Using Percentage Discount for Tier Prices MAGETWO-55258: Update Indexer --- .../Indexer/Product/Price/AbstractAction.php | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php index 720e491cef0..464adb27686 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Price/AbstractAction.php @@ -70,6 +70,11 @@ abstract class AbstractAction */ protected $_indexers; + /** + * @var \Magento\Catalog\Model\ResourceModel\Product + */ + private $productResource; + /** * @param \Magento\Framework\App\Config\ScopeConfigInterface $config * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -213,12 +218,19 @@ abstract class AbstractAction $table = $this->_defaultIndexerResource->getTable('catalog_product_index_tier_price'); $this->_emptyTable($table); + $tierPriceExpression = $this->_connection->getCheckSql( + 'tp.value = 0', + 'product_price.value * (1 - tp.percentage_value / 100)', + 'tp.value' + ); $websiteExpression = $this->_connection->getCheckSql( 'tp.website_id = 0', - 'ROUND(tp.value * cwd.rate, 4)', - 'tp.value' + 'ROUND(' . $tierPriceExpression . ' * cwd.rate, 4)', + $tierPriceExpression ); $linkField = $this->getProductIdFieldName(); + $priceAttribute = $this->getProductResource()->getAttribute('price'); + $select = $this->_connection->select()->from( ['cpe' => $this->_defaultIndexerResource->getTable('catalog_product_entity')], ['cpe.entity_id'] @@ -238,8 +250,15 @@ abstract class AbstractAction ['cwd' => $this->_defaultIndexerResource->getTable('catalog_product_index_website')], 'cw.website_id = cwd.website_id', [] + )->join( + ['product_price' => $priceAttribute->getBackend()->getTable()], + 'tp.' . $linkField . ' = product_price.' . $linkField, + [] )->where( 'cw.website_id != 0' + )->where( + 'product_price.attribute_id = ?', + $priceAttribute->getAttributeId() )->columns( new \Zend_Db_Expr("MIN({$websiteExpression})") )->group( @@ -462,4 +481,17 @@ abstract class AbstractAction $indexList = $this->_connection->getIndexList($table); return $indexList[$this->_connection->getPrimaryKeyName($table)]['COLUMNS_LIST'][0]; } + + /** + * @return \Magento\Catalog\Model\ResourceModel\Product + * @deprecated + */ + private function getProductResource() + { + if (null === $this->productResource) { + $this->productResource = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Catalog\Model\ResourceModel\Product::class); + } + return $this->productResource; + } } -- GitLab From e93256150f4d878d9da8733d62429b3d4bdf9971 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 21 Jul 2016 14:26:24 +0300 Subject: [PATCH 576/838] MAGETWO-55261: Update Advanced Pricing Popup on product page - tierprice fixes --- .../Model/Product/Attribute/Backend/Tierprice.php | 14 -------------- 1 file changed, 14 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 a8733a0730a..0882592ee2f 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -106,20 +106,6 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr return false; } - /** - * @inheritdoc - */ - protected function modifyPriceData($object, $data) - { - foreach ($data as $key => $tierPrice) { - if ($tierPrice['percentage_value'] > 0) { - $data[$key]['price'] = $object->getPrice() * (1 - $tierPrice['percentage_value'] / 100); - } - } - - return parent::modifyPriceData($object, $data); - } - /** * @inheritdoc */ -- GitLab From bd3ad3af3380afbd030f673f5c20ca5032ebe62e Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Thu, 21 Jul 2016 18:27:11 +0300 Subject: [PATCH 577/838] MAGETWO-49543: Using Percentage Discount for Tier Prices MAGETWO-55780: Wrong logic of tier price loading --- .../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 0882592ee2f..056c9053425 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -126,4 +126,18 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr return parent::validate($object); } + + /** + * @inheritdoc + */ + protected function modifyPriceData($object, $data) + { + $data = parent::modifyPriceData($object, $data); + foreach ($data as $key => $tierPrice) { + if ($tierPrice['percentage_value'] > 0) { + $data[$key]['website_price'] = $object->getPrice() * (1 - $tierPrice['percentage_value'] / 100); + } + } + return $data; + } } -- GitLab From 915b45b556b9547c03008061f4eae3a1dd798b8b Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Thu, 21 Jul 2016 21:38:52 +0300 Subject: [PATCH 578/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - Added rule for percentage value in validation --- .../Attribute/Backend/GroupPrice/AbstractGroupPrice.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index e7b242aea40..cd1b855afc1 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -176,7 +176,8 @@ abstract class AbstractGroupPrice extends Price throw new \Magento\Framework\Exception\LocalizedException(__($this->_getDuplicateErrorMessage())); } - if (!$this->isPositiveOrZero($priceRow['price'])) { + if ((!isset($priceRow['price']) || !$this->isPositiveOrZero($priceRow['price'])) + && (!isset($priceRow['percentage_value']) || !$this->isPositiveOrZero($priceRow['percentage_value']))) { return __('Group price must be a number greater than 0.'); } -- GitLab From a7d3b2968742a86a7180c4d8cd3f762ecb8443c1 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 22 Jul 2016 14:10:10 +0300 Subject: [PATCH 579/838] MAGETWO-49543: Using Percentage Discount for Tier Prices MAGETWO-55263: Add Functional\Zephyr tests --- .../Test/Handler/CatalogProductSimple/Webapi.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php index f3d839ecf8a..4ec372ab716 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Webapi.php @@ -347,8 +347,16 @@ class Webapi extends AbstractWebApi implements CatalogProductSimpleInterface $priceInfo['customer_group_id'] = $priceInfo['cust_group']; unset($priceInfo['cust_group']); - $priceInfo['value'] = $priceInfo['price']; - unset($priceInfo['price']); + if (isset($priceInfo['price'])) { + $priceInfo['value'] = $priceInfo['price']; + unset($priceInfo['price']); + } + unset($priceInfo['value_type']); + + if (isset($priceInfo['percentage_value'])) { + $priceInfo['extension_attributes']['percentage_value'] = $priceInfo['percentage_value']; + unset($priceInfo['percentage_value']); + } $priceInfo['qty'] = $priceInfo['price_qty']; unset($priceInfo['price_qty']); -- GitLab From 5862de42cbffe6459bf88296abd79c0e9f97d9c0 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda <vnayda@magento.com> Date: Fri, 22 Jul 2016 14:50:53 +0300 Subject: [PATCH 580/838] MAGETWO-49543: Using Percentage Discount for Tier Prices MAGETWO-55840: Problem with tier price deleting on product page --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 6 +++++- 1 file changed, 5 insertions(+), 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 056c9053425..9f98a52adc7 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -116,7 +116,11 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr $priceRows = array_filter((array)$priceRows); foreach ($priceRows as $priceRow) { - $percentage = isset($priceRow['percentage_value']) ? $priceRow['percentage_value'] : 0 ; + $percentage = isset($priceRow['percentage_value']) ? $priceRow['percentage_value'] : 0; + if ($percentage == '') { + // TODO: MAGETWO-55839 + continue; + } if (!is_numeric($percentage) || $percentage < 0 || $percentage > 100) { throw new \Magento\Framework\Exception\LocalizedException( __('Percentage value must be a number between 0 and 100.') -- GitLab From 7b7aaa95ead3cc1e89eccc76342cc5f4c8b2c0a1 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Fri, 22 Jul 2016 21:50:38 +0300 Subject: [PATCH 581/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55521 Save price data --- ...pedProductTierPriceManagementInterface.php | 45 +++++ .../Product/ScopedTierPriceManagement.php | 185 ++++++++++++++++++ .../Catalog/Model/Product/TierPrice.php | 7 + app/code/Magento/Catalog/etc/di.xml | 1 + 4 files changed, 238 insertions(+) create mode 100644 app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php create mode 100644 app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php diff --git a/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php b/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php new file mode 100644 index 00000000000..8a27480b776 --- /dev/null +++ b/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php @@ -0,0 +1,45 @@ +<?php +/** + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Api; + +/** + * @api + */ +interface ScopedProductTierPriceManagementInterface +{ + /** + * Create tier price for product + * + * @param string $sku + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice + * @return boolean + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function add($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice); + + /** + * Remove tier price from product + * + * @param string $sku + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice + * @return boolean + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\CouldNotSaveException + */ + public function remove($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice); + + /** + * Get tier price of product + * + * @param string $sku + * @param string $customerGroupId 'all' can be used to specify 'ALL GROUPS' + * @return \Magento\Catalog\Api\Data\ProductTierPriceInterface[] + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function getList($sku, $customerGroupId); +} diff --git a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php new file mode 100644 index 00000000000..04d04af9ecb --- /dev/null +++ b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php @@ -0,0 +1,185 @@ +<?php +/** + * + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\Product; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Customer\Api\GroupManagementInterface; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Framework\Exception\InputException; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTierPriceManagementInterface +{ + /** + * @var \Magento\Catalog\Api\ProductRepositoryInterface + */ + protected $productRepository; + + /** + * @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory + */ + protected $priceFactory; + + /** + * @var \Magento\Store\Model\StoreManagerInterface + */ + protected $storeManager; + + /** + * @var \Magento\Catalog\Model\Product\PriceModifier + */ + protected $priceModifier; + + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface + */ + protected $config; + + /** + * @var GroupManagementInterface + */ + protected $groupManagement; + + /** + * @param ProductRepositoryInterface $productRepository + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $priceFactory + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param PriceModifier $priceModifier + * @param \Magento\Framework\App\Config\ScopeConfigInterface $config + * @param GroupManagementInterface $groupManagement + */ + public function __construct( + ProductRepositoryInterface $productRepository, + \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $priceFactory, + \Magento\Store\Model\StoreManagerInterface $storeManager, + \Magento\Catalog\Model\Product\PriceModifier $priceModifier, + \Magento\Framework\App\Config\ScopeConfigInterface $config, + GroupManagementInterface $groupManagement + ) { + $this->productRepository = $productRepository; + $this->priceFactory = $priceFactory; + $this->storeManager = $storeManager; + $this->priceModifier = $priceModifier; + $this->config = $config; + $this->groupManagement = $groupManagement; + } + + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function add($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) + { + $this->validatePrice($tierPrice); + $product = $this->productRepository->get($sku, ['edit_mode' => true]); + $tierPrices = $product->getTierPrices(); + $websiteIdentifier = 0; + $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); + if ($value != 0) { + $websiteIdentifier = $this->storeManager->getWebsite()->getId(); + } + $found = false; + + foreach ($tierPrices as $item) { + $tierPriceWebsite = $tierPrice->getExtensionAttributes() ? $tierPrice->getExtensionAttributes()->getWebsiteId() : 0; + if ($item->getCustomerGroupId() == $tierPrice->getCustomerGroupId() + && $websiteIdentifier == $tierPriceWebsite + && $item->getQty() == $tierPrice->getQty()) { + $item->setValue($tierPrice->getValue()); + $item->getExtensionAttributes() + ->setPercentageValue($tierPrice->getExtensionAttributes()->getPercentageValue()); + $found = true; + break; + } + } + if (!$found) { + $tierPrices[] = $tierPrice; + } + + $product->setTierPrices($tierPrices); + $errors = $product->validate(); + if (is_array($errors) && count($errors)) { + $errorAttributeCodes = implode(', ', array_keys($errors)); + throw new InputException( + __('Values of following attributes are invalid: %1', $errorAttributeCodes) + ); + } + try { + $this->productRepository->save($product); + } catch (\Exception $e) { + throw new CouldNotSaveException(__('Could not save group price')); + } + return true; + } + + protected function validatePrice(\Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) + { + $data = ['qty' => $tierPrice->getQty()]; + foreach ($data as $value) { + if (!\Zend_Validate::is($value, 'Float') || $value <= 0) { + throw new InputException(__('Please provide valid data')); + } + } + } + + /** + * {@inheritdoc} + */ + public function remove($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) + { + $product = $this->productRepository->get($sku, ['edit_mode' => true]); + $websiteIdentifier = 0; + $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); + if ($value != 0) { + $websiteIdentifier = $this->storeManager->getWebsite()->getId(); + } + $this->priceModifier->removeTierPrice( + $product, + $tierPrice->getCustomerGroupId(), + $tierPrice->getQty(), + $websiteIdentifier) + ; + return true; + } + + /** + * {@inheritdoc} + */ + public function getList($sku, $customerGroupId) + { + $product = $this->productRepository->get($sku, ['edit_mode' => true]); + + $priceKey = 'website_price'; + $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); + if ($value == 0) { + $priceKey = 'price'; + } + + $cgi = ($customerGroupId === 'all' + ? $this->groupManagement->getAllCustomersGroup()->getId() + : $customerGroupId); + + $prices = []; + foreach ($product->getData('tier_price') as $price) { + if ((is_numeric($customerGroupId) && intval($price['cust_group']) === intval($customerGroupId)) + || ($customerGroupId === 'all' && $price['all_groups']) + ) { + /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice */ + $tierPrice = $this->priceFactory->create(); + $tierPrice->setValue($price[$priceKey]) + ->setQty($price['price_qty']) + ->setCustomerGroupId($cgi); + $prices[] = $tierPrice; + } + } + return $prices; + } +} diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 131280af1b1..fa321f34174 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -6,6 +6,7 @@ */ namespace Magento\Catalog\Model\Product; +use Magento\Framework\App\ObjectManager; /** * @codeCoverageIgnore @@ -83,6 +84,12 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme */ public function getExtensionAttributes() { + if (empty($this->_getExtensionAttributes())) { + $this->setExtensionAttributes( + ObjectManager::getInstance()->get('\Magento\Framework\Api\ExtensionAttributesFactory') + ->create('Magento\Catalog\Api\Data\ProductTierPriceInterface') + ); + } return $this->_getExtensionAttributes(); } diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 8163def574f..49ad7d67d70 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -471,6 +471,7 @@ <preference for="Magento\Catalog\Api\ProductCustomOptionRepositoryInterface" type="\Magento\Catalog\Model\Product\Option\Repository" /> <preference for="Magento\Catalog\Api\Data\ProductCustomOptionTypeInterface" type="Magento\Catalog\Model\Product\Option\Type" /> <preference for="Magento\Catalog\Api\ProductTierPriceManagementInterface" type="\Magento\Catalog\Model\Product\TierPriceManagement" /> + <preference for="Magento\Catalog\Api\ScopedProductTierPriceManagementInterface" type="\Magento\Catalog\Model\Product\ScopedTierPriceManagement" /> <preference for="Magento\Catalog\Api\Data\ProductTierPriceInterface" type="Magento\Catalog\Model\Product\TierPrice" /> <preference for="Magento\Catalog\Api\Data\CategoryProductLinkInterface" type="Magento\Catalog\Model\CategoryProductLink" /> <preference for="Magento\Catalog\Api\ProductCustomOptionTypeListInterface" type="Magento\Catalog\Model\ProductOptions\TypeList" /> -- GitLab From 6f0ae4e28cb4415a68a63c60727d4d38d1eee9d4 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Fri, 22 Jul 2016 22:00:59 +0300 Subject: [PATCH 582/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55521: Save price data --- .../Attribute/Backend/GroupPrice/AbstractGroupPrice.php | 1 + .../Catalog/Model/Product/ScopedTierPriceManagement.php | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index cd1b855afc1..13e4f61bdf5 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -319,6 +319,7 @@ abstract class AbstractGroupPrice extends Price * @param \Magento\Catalog\Model\Product $object * @param array $data * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function modifyPriceData($object, $data) { diff --git a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php index 04d04af9ecb..ca5c61551da 100644 --- a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php +++ b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php @@ -89,7 +89,8 @@ class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTie $found = false; foreach ($tierPrices as $item) { - $tierPriceWebsite = $tierPrice->getExtensionAttributes() ? $tierPrice->getExtensionAttributes()->getWebsiteId() : 0; + $tierPriceWebsite = + $tierPrice->getExtensionAttributes() ? $tierPrice->getExtensionAttributes()->getWebsiteId() : 0; if ($item->getCustomerGroupId() == $tierPrice->getCustomerGroupId() && $websiteIdentifier == $tierPriceWebsite && $item->getQty() == $tierPrice->getQty()) { @@ -145,8 +146,8 @@ class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTie $product, $tierPrice->getCustomerGroupId(), $tierPrice->getQty(), - $websiteIdentifier) - ; + $websiteIdentifier + ); return true; } -- GitLab From 30202dd42c30450f36ed5c613be2e4391e626e25 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Fri, 22 Jul 2016 22:37:25 +0300 Subject: [PATCH 583/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55521: Save price data --- .../Catalog/Model/Product/ScopedTierPriceManagement.php | 5 +++++ app/code/Magento/Catalog/Model/Product/TierPrice.php | 1 + 2 files changed, 6 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php index ca5c61551da..51924fbda8d 100644 --- a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php +++ b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php @@ -121,6 +121,11 @@ class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTie return true; } + /** + * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice + * @throws InputException + * @throws \Zend_Validate_Exception + */ protected function validatePrice(\Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) { $data = ['qty' => $tierPrice->getQty()]; diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index fa321f34174..c866ee8895d 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -6,6 +6,7 @@ */ namespace Magento\Catalog\Model\Product; + use Magento\Framework\App\ObjectManager; /** -- GitLab From 34b5ae057488e9e2689872944216321d53bced5b Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Mon, 25 Jul 2016 11:21:00 +0300 Subject: [PATCH 584/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55521: Save price data --- .../Magento/Catalog/Model/Product/ScopedTierPriceManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php index 51924fbda8d..34f90331ddd 100644 --- a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php +++ b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php @@ -123,6 +123,7 @@ class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTie /** * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice + * @return void * @throws InputException * @throws \Zend_Validate_Exception */ -- GitLab From d6236b23658cc6924186dcb2f3fb78c3f287661c Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:50:17 +0300 Subject: [PATCH 585/838] MAGETWO-49543: Using Percentage Discount for Tier Prices --- .../Backend/GroupPrice/AbstractGroupPrice.php | 78 +++++++++++++------ .../Product/Attribute/Backend/Tierprice.php | 74 ++++++++++++++++-- .../Catalog/Model/Product/Type/Price.php | 9 +-- .../Magento/Catalog/Setup/UpgradeSchema.php | 3 +- .../Unit/Model/Product/Type/PriceTest.php | 22 +++--- 5 files changed, 139 insertions(+), 47 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index 13e4f61bdf5..9edb3e81c8f 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -129,6 +129,18 @@ abstract class AbstractGroupPrice extends Price return []; } + /** + * Get additional fields + * + * @param array $objectArray + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function getAdditionalFields($objectArray) + { + return []; + } + /** * Whether group price value fixed or percent of original price * @@ -176,10 +188,7 @@ abstract class AbstractGroupPrice extends Price throw new \Magento\Framework\Exception\LocalizedException(__($this->_getDuplicateErrorMessage())); } - if ((!isset($priceRow['price']) || !$this->isPositiveOrZero($priceRow['price'])) - && (!isset($priceRow['percentage_value']) || !$this->isPositiveOrZero($priceRow['percentage_value']))) { - return __('Group price must be a number greater than 0.'); - } + $this->validatePrice($priceRow); $duplicates[$compare] = true; } @@ -229,6 +238,20 @@ abstract class AbstractGroupPrice extends Price return true; } + /** + * @param array $priceRow + * @return void + * @throws \Magento\Framework\Exception\LocalizedException + */ + protected function validatePrice(array $priceRow) + { + if (!isset($priceRow['price']) || !$this->isPositiveOrZero($priceRow['price'])) { + throw new \Magento\Framework\Exception\LocalizedException( + __('Group price must be a number greater than 0.') + ); + } + } + /** * Prepare group prices data for website * @@ -324,7 +347,9 @@ abstract class AbstractGroupPrice extends Price protected function modifyPriceData($object, $data) { foreach ($data as $k => $v) { - $data[$k]['website_price'] = $v['price']; + if (isset($v['price']) && $v['price'] > 0) { + $data[$k]['website_price'] = $v['price']; + } if ($v['all_groups']) { $data[$k]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId(); } @@ -401,14 +426,13 @@ abstract class AbstractGroupPrice extends Price $useForAllGroups = $data['cust_group'] == $this->_groupManagement->getAllCustomersGroup()->getId(); $customerGroupId = !$useForAllGroups ? $data['cust_group'] : 0; - $isPercentageValue = isset($data['percentage_value']) && $data['percentage_value'] > 0; $new[$key] = array_merge( + $this->getAdditionalFields($data), [ 'website_id' => $data['website_id'], 'all_groups' => $useForAllGroups ? 1 : 0, 'customer_group_id' => $customerGroupId, - 'value' => $isPercentageValue ? 0 : $data['price'], - 'percentage_value' => $isPercentageValue ? $data['percentage_value'] : 0, + 'value' => isset($data['price']) ? $data['price'] : null, ], $this->_getAdditionalUniqueFields($data) ); @@ -442,20 +466,7 @@ abstract class AbstractGroupPrice extends Price } if (!empty($update)) { - foreach ($update as $k => $v) { - if ($old[$k]['price'] != $v['value'] || $old[$k]['percentage_value'] != $v['percentage_value']) { - $price = new \Magento\Framework\DataObject( - [ - 'value_id' => $old[$k]['price_id'], - 'value' => $v['value'], - 'percentage_value' => $v['percentage_value'] - ] - ); - $this->_getResource()->savePriceData($price); - - $isChanged = true; - } - } + $isChanged = $this->updateValues($update, $old); } if ($isChanged) { @@ -466,6 +477,29 @@ abstract class AbstractGroupPrice extends Price return $this; } + /** + * @param array $valuesToUpdate + * @param array $oldValues + * @return boolean + */ + protected function updateValues(array $valuesToUpdate, array $oldValues) + { + $isChanged = false; + foreach ($valuesToUpdate as $key => $value) { + if ($oldValues[$key]['price'] != $value['value']) { + $price = new \Magento\Framework\DataObject( + [ + 'value_id' => $oldValues[$key]['price_id'], + 'value' => $value['value'] + ] + ); + $this->_getResource()->savePriceData($price); + $isChanged = true; + } + } + return $isChanged; + } + /** * Retrieve data for update attribute * 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 9f98a52adc7..890f186c847 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -75,6 +75,18 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr return $uniqueFields; } + /** + * @inheritdoc + */ + protected function getAdditionalFields($objectArray) + { + $percentageValue = $this->getPercentage($objectArray); + return [ + 'value' => $percentageValue ? null : $objectArray['price'], + 'percentage_value' => $percentageValue ?: null, + ]; + } + /** * Error message when duplicates * @@ -116,12 +128,8 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr $priceRows = array_filter((array)$priceRows); foreach ($priceRows as $priceRow) { - $percentage = isset($priceRow['percentage_value']) ? $priceRow['percentage_value'] : 0; - if ($percentage == '') { - // TODO: MAGETWO-55839 - continue; - } - if (!is_numeric($percentage) || $percentage < 0 || $percentage > 100) { + $percentage = $this->getPercentage($priceRow); + if ($percentage !== null && (!$this->isPositiveOrZero($percentage) || $percentage > 100)) { throw new \Magento\Framework\Exception\LocalizedException( __('Percentage value must be a number between 0 and 100.') ); @@ -131,6 +139,16 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr return parent::validate($object); } + /** + * @inheritdoc + */ + protected function validatePrice(array $priceRow) + { + if (!$this->getPercentage($priceRow)) { + parent::validatePrice($priceRow); + } + } + /** * @inheritdoc */ @@ -138,10 +156,50 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr { $data = parent::modifyPriceData($object, $data); foreach ($data as $key => $tierPrice) { - if ($tierPrice['percentage_value'] > 0) { - $data[$key]['website_price'] = $object->getPrice() * (1 - $tierPrice['percentage_value'] / 100); + if ($this->getPercentage($tierPrice)) { + $data[$key]['website_price'] = $object->getPrice() * (1 - $this->getPercentage($tierPrice) / 100); } } return $data; } + + /** + * @param array $valuesToUpdate + * @param array $oldValues + * @return boolean + */ + protected function updateValues(array $valuesToUpdate, array $oldValues) + { + $isChanged = false; + foreach ($valuesToUpdate as $key => $value) { + if ($oldValues[$key]['price'] != $value['value'] + || $this->getPercentage($oldValues[$key]) != $this->getPercentage($value) + ) { + $price = new \Magento\Framework\DataObject( + [ + 'value_id' => $oldValues[$key]['price_id'], + 'value' => $value['value'], + 'percentage_value' => $this->getPercentage($value) + ] + ); + $this->_getResource()->savePriceData($price); + + $isChanged = true; + } + } + return $isChanged; + } + + /** + * Check whether price has percentage value. + * + * @param $priceRow + * @return null + */ + private function getPercentage($priceRow) + { + return isset($priceRow['percentage_value']) && is_numeric($priceRow['percentage_value']) + ? $priceRow['percentage_value'] + : null; + } } diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index 4ce3c47e231..6684555de3c 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -360,7 +360,8 @@ class Price $tierPrices = $this->getExistingPrices($product, 'tier_price'); foreach ($tierPrices as $price) { /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice */ - $tierPrice = $this->tierPriceFactory->create(); + $tierPrice = $this->tierPriceFactory->create() + ->setExtensionAttributes($this->getTierPriceExtensionAttributes()); $tierPrice->setCustomerGroupId($price['cust_group']); if (array_key_exists('website_price', $price)) { $value = $price['website_price']; @@ -369,12 +370,10 @@ class Price } $tierPrice->setValue($value); $tierPrice->setQty($price['price_qty']); - if (!$tierPrice->getExtensionAttributes()) { - $tierPrice->setExtensionAttributes($this->getTierPriceExtensionAttributes()); + if (isset($price['percentage_value'])) { + $tierPrice->getExtensionAttributes()->setPercentageValue($price['percentage_value']); } - $percentageValue = isset($price['percentage_value']) ? $price['percentage_value'] : 0; $websiteId = isset($price['website_id']) ? $price['website_id'] : $this->getWebsiteForPriceScope(); - $tierPrice->getExtensionAttributes()->setPercentageValue($percentageValue); $tierPrice->getExtensionAttributes()->setWebsiteId($websiteId); $prices[] = $tierPrice; } diff --git a/app/code/Magento/Catalog/Setup/UpgradeSchema.php b/app/code/Magento/Catalog/Setup/UpgradeSchema.php index 8ae9bd5e9c3..9683632f121 100644 --- a/app/code/Magento/Catalog/Setup/UpgradeSchema.php +++ b/app/code/Magento/Catalog/Setup/UpgradeSchema.php @@ -296,8 +296,7 @@ class UpgradeSchema implements UpgradeSchemaInterface 'percentage_value', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL, - 'nullable' => false, - 'default' => '0.00', + 'nullable' => true, 'length' => '5,2', 'comment' => 'Percentage value', 'after' => 'value' diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index 04b39003f72..2b98c106acc 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -62,7 +62,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->objectManagerHelper = new ObjectManagerHelper($this); $this->product = $this->objectManagerHelper->getObject(\Magento\Catalog\Model\Product::class); - $this->tpFactory = $this->getMockForAbstractClass( + $this->tpFactory = $this->getMockForAbstractClass( \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class, [], '', @@ -73,7 +73,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase ); $this->websiteMock = $this->getMock(\Magento\Store\Model\Website::class, ['getId'], [], '', false); - $storeMangerMock = $this->getMockForAbstractClass( + $storeMangerMock = $this->getMockForAbstractClass( \Magento\Store\Model\StoreManagerInterface::class, [], '', @@ -86,7 +86,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase ->method('getWebsite') ->will($this->returnValue($this->websiteMock)); - $this->scopeConfigMock = $this->getMockForAbstractClass( + $this->scopeConfigMock = $this->getMockForAbstractClass( \Magento\Framework\App\Config\ScopeConfigInterface::class, [], '', @@ -96,7 +96,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase ['getValue'] ); - $group = $this->getMock( + $group = $this->getMock( \Magento\Customer\Model\Data\Group::class, [], [], @@ -109,7 +109,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->groupManagementMock->expects($this->any())->method('getAllCustomersGroup') ->will($this->returnValue($group)); - $this->model = $this->objectManagerHelper->getObject( + $this->model = $this->objectManagerHelper->getObject( \Magento\Catalog\Model\Product\Type\Price::class, [ 'tierPriceFactory' => $this->tpFactory, @@ -179,14 +179,18 @@ class PriceTest extends \PHPUnit_Framework_TestCase })); // create sample TierPrice objects that would be coming from a REST call - $tp1 = $this->objectManagerHelper->getObject(\Magento\Catalog\Model\Product\TierPrice::class); + $tierPriceExtensionMock = $this->getMockBuilder(ProductTierPriceExtensionInterface::class)->getMock(); + $tierPriceExtensionMock->expects($this->any())->method('getWebsiteId')->willReturn($expectedWebsiteId); + $tp1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); $tp1->setValue(10); $tp1->setCustomerGroupId(1); $tp1->setQty(11); - $tp2 = $this->objectManagerHelper->getObject(\Magento\Catalog\Model\Product\TierPrice::class); + $tp1->setExtensionAttributes($tierPriceExtensionMock); + $tp2 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); $tp2->setValue(20); $tp2->setCustomerGroupId(2); $tp2->setQty(22); + $tp2->setExtensionAttributes($tierPriceExtensionMock); $tps = [$tp1, $tp2]; // force the product to have null tier prices @@ -215,9 +219,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->assertEquals($tps[$i]->getQty(), $tpData['price_qty'], 'Qty does not match'); } - $tierPriceExtention = $this->getMockBuilder(ProductTierPriceExtensionInterface::class) - ->setMethods(['setWebsiteId', 'setPercentageValue', 'getPercentageValue']) - ->disableOriginalConstructor()->getMock(); + $tierPriceExtention = $this->getMockBuilder(ProductTierPriceExtensionInterface::class)->getMock(); $tierPriceExtention->expects($this->any())->method('getPercentageValue')->willReturn(50); $factoryMock = $this->getMockBuilder(ProductTierPriceExtensionFactory::class)->setMethods(['create']) ->disableOriginalConstructor()->getMock(); -- GitLab From a00374191ac70d725f29d272036fccea30b75307 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 26 Jul 2016 15:34:53 +0300 Subject: [PATCH 586/838] MAGETWO-49543: Using Percentage Discount for Tier Prices --- app/code/Magento/Catalog/Model/Product/Type/Price.php | 7 +++++-- .../testsuite/Magento/Catalog/_files/product_simple.php | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index 6684555de3c..af15e049203 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -414,14 +414,17 @@ class Price $prices = []; foreach ($tierPrices as $price) { $extensionAttributes = $price->getExtensionAttributes(); + $websiteId = $extensionAttributes && $extensionAttributes->getWebsiteId() + ? $extensionAttributes->getWebsiteId() + : $websiteId; $prices[] = [ - 'website_id' => $extensionAttributes ? $extensionAttributes->getWebsiteId() : $websiteId, + 'website_id' => $websiteId, 'cust_group' => $price->getCustomerGroupId(), 'website_price' => $price->getValue(), 'price' => $price->getValue(), 'all_groups' => ($price->getCustomerGroupId() == $allGroupsId), 'price_qty' => $price->getQty(), - 'percentage_value' => $extensionAttributes ? $extensionAttributes->getPercentageValue() : 0 + 'percentage_value' => $extensionAttributes ? $extensionAttributes->getPercentageValue() : null ]; } $product->setData('tier_price', $prices); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 6f84bed99c3..5154726a83b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -42,15 +42,18 @@ $tierPrices[] = $tierPriceFactory->create( ] ] ); +/** @var $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->create(\Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory::class); +$tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); + $tierPrices[] = $tierPriceFactory->create( [ 'data' => [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, - 'qty' => 10, - 'percentage_value' => 50 + 'qty' => 10 ] ] -); +)->setExtensionAttributes($tpExtensionAttributes); /** @var $product \Magento\Catalog\Model\Product */ $product = $objectManager->create(\Magento\Catalog\Model\Product::class); -- GitLab From 0776843fd6c670700a7204b9462cbd3df928743c Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Tue, 26 Jul 2016 18:15:44 +0300 Subject: [PATCH 587/838] MAGETWO-49543: Using Percentage Discount for Tier Prices --- .../Catalog/Model/Product/Attribute/Backend/Tierprice.php | 2 +- .../testsuite/Magento/Catalog/_files/product_simple.php | 4 +++- 2 files changed, 4 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 890f186c847..480f8e8942e 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -193,7 +193,7 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr /** * Check whether price has percentage value. * - * @param $priceRow + * @param array $priceRow * @return null */ private function getPercentage($priceRow) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 5154726a83b..63b7a28b50b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; + \Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize(); /** @var \Magento\TestFramework\ObjectManager $objectManager */ @@ -43,7 +45,7 @@ $tierPrices[] = $tierPriceFactory->create( ] ); /** @var $tpExtensionAttributes */ -$tpExtensionAttributesFactory = $objectManager->create(\Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory::class); +$tpExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); $tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); $tierPrices[] = $tierPriceFactory->create( -- GitLab From 330c31968dded372f49996871da222d9e4a1a127 Mon Sep 17 00:00:00 2001 From: Anton Ohorodnyk <aohorodnyk@magento.com> Date: Mon, 1 Aug 2016 16:21:43 +0300 Subject: [PATCH 588/838] MAGETWO-49545: [JS] Adding a Field Shortcut to Calculate Price using % - Fixed mixin for keeping old validation --- .../Product/Form/Modifier/AdvancedPricing.php | 2 +- .../web/js/form/element/price-input.js | 23 +++++++++++++++++++ .../view/adminhtml/web/js/price-input.js | 11 --------- .../template/form/element/price-input.html | 22 ++++++++++++++++++ 4 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js delete mode 100644 app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js create mode 100644 app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 13a99f9e98c..a01d5bcf546 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -497,7 +497,7 @@ class AdvancedPricing extends AbstractModifier 'data' => [ 'config' => [ 'componentType' => Field::NAME, - 'component' => 'Magento_Catalog/js/price-input', + 'component' => 'Magento_Catalog/js/form/element/price-input', 'formElement' => Input::NAME, 'dataType' => Price::NAME, 'label' => __('Price'), diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js new file mode 100644 index 00000000000..91132efa56a --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js @@ -0,0 +1,23 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define([ + 'Magento_Ui/js/form/element/abstract' +], function (Abstract) { + 'use strict'; + + return Abstract.extend({ + defaults: { + elementTmpl: 'Magento_Catalog/form/element/price-input' + }, + + /** + * Callback that fires when 'input' event is performed + * + * @param {Object} data + * @param {Object} event + */ + onInput: function (data, event) {} + }); +}); diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js deleted file mode 100644 index 871896257ab..00000000000 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/price-input.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -define([ - 'Magento_Ui/js/form/element/abstract' -], function (Abstract) { - 'use strict'; - - return Abstract.extend({}); -}); diff --git a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html new file mode 100644 index 00000000000..ce8ae751e67 --- /dev/null +++ b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html @@ -0,0 +1,22 @@ +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<input class="admin__control-text" type="text" + data-bind=" + event: { + change: userChanges, + input: onInput + }, + value: value, + hasFocus: focused, + valueUpdate: valueUpdate, + attr: { + name: inputName, + placeholder: placeholder, + 'aria-describedby': noticeId, + id: uid, + disabled: disabled + }"/> -- GitLab From bce1f5c0b067742b396f096a91acaaece5489517 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:51:24 +0300 Subject: [PATCH 589/838] MAGETWO-55908: Prepare PR --- .../Unit/Model/Product/Type/PriceTest.php | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index 2b98c106acc..7c4aba1c4be 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -64,12 +64,11 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->tpFactory = $this->getMockForAbstractClass( \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class, - [], + ['create'], '', false, - true, - true, - ['create'] + false, + false ); $this->websiteMock = $this->getMock(\Magento\Store\Model\Website::class, ['getId'], [], '', false); @@ -166,12 +165,8 @@ class PriceTest extends \PHPUnit_Framework_TestCase public function testTierPrices($priceScope, $expectedWebsiteId) { // establish the behavior of the mocks - $this->scopeConfigMock->expects($this->any()) - ->method('getValue') - ->will($this->returnValue($priceScope)); - $this->websiteMock->expects($this->any()) - ->method('getId') - ->will($this->returnValue($expectedWebsiteId)); + $this->scopeConfigMock->expects($this->any())->method('getValue')->will($this->returnValue($priceScope)); + $this->websiteMock->expects($this->any())->method('getId')->will($this->returnValue($expectedWebsiteId)); $this->tpFactory->expects($this->any()) ->method('create') ->will($this->returnCallback(function () { @@ -179,8 +174,11 @@ class PriceTest extends \PHPUnit_Framework_TestCase })); // create sample TierPrice objects that would be coming from a REST call - $tierPriceExtensionMock = $this->getMockBuilder(ProductTierPriceExtensionInterface::class)->getMock(); + $tierPriceExtensionMock = $this->getMockBuilder(ProductTierPriceExtensionInterface::class) + ->setMethods(['getWebsiteId', 'getPercentageValue']) + ->getMock(); $tierPriceExtensionMock->expects($this->any())->method('getWebsiteId')->willReturn($expectedWebsiteId); + $tierPriceExtensionMock->expects($this->any())->method('getPercentageValue')->willReturn(null); $tp1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); $tp1->setValue(10); $tp1->setCustomerGroupId(1); @@ -219,8 +217,11 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->assertEquals($tps[$i]->getQty(), $tpData['price_qty'], 'Qty does not match'); } - $tierPriceExtention = $this->getMockBuilder(ProductTierPriceExtensionInterface::class)->getMock(); + $tierPriceExtention = $this->getMockBuilder(ProductTierPriceExtensionInterface::class) + ->setMethods(['getWebsiteId', 'getPercentageValue', 'setWebsiteId']) + ->getMock(); $tierPriceExtention->expects($this->any())->method('getPercentageValue')->willReturn(50); + $tierPriceExtention->expects($this->any())->method('setWebsiteId'); $factoryMock = $this->getMockBuilder(ProductTierPriceExtensionFactory::class)->setMethods(['create']) ->disableOriginalConstructor()->getMock(); $factoryMock->expects($this->any())->method('create')->willReturn($tierPriceExtention); -- GitLab From f57a5d9feadfc96b14b7dc53d3034b6242ab2710 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:52:20 +0300 Subject: [PATCH 590/838] MAGETWO-55908: Prepare PR --- .../Catalog/Test/Unit/Model/Product/Type/PriceTest.php | 4 ++-- .../Catalog/Model/ResourceModel/Product/CollectionTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index 7c4aba1c4be..afe22b888b2 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -179,12 +179,12 @@ class PriceTest extends \PHPUnit_Framework_TestCase ->getMock(); $tierPriceExtensionMock->expects($this->any())->method('getWebsiteId')->willReturn($expectedWebsiteId); $tierPriceExtensionMock->expects($this->any())->method('getPercentageValue')->willReturn(null); - $tp1 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); + $tp1 = $this->objectManagerHelper->getObject(\Magento\Catalog\Model\Product\TierPrice::class); $tp1->setValue(10); $tp1->setCustomerGroupId(1); $tp1->setQty(11); $tp1->setExtensionAttributes($tierPriceExtensionMock); - $tp2 = $this->objectManagerHelper->getObject('Magento\Catalog\Model\Product\TierPrice'); + $tp2 = $this->objectManagerHelper->getObject(\Magento\Catalog\Model\Product\TierPrice::class); $tp2->setValue(20); $tp2->setCustomerGroupId(2); $tp2->setQty(22); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php index 0d4a2c7363a..7f13f6c9c52 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php @@ -37,7 +37,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase ); $this->productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Api\ProductRepositoryInterface' + \Magento\Catalog\Api\ProductRepositoryInterface::class ); } -- GitLab From 967ee1a0ce5af580afcc48369466dbd0fd65734d Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 17:54:07 +0300 Subject: [PATCH 591/838] MAGETWO-55908: Prepare PR --- .../Catalog/Model/Product/TierPrice.php | 4 +- .../Unit/Model/Product/Type/PriceTest.php | 6 ++- .../Product/Form/Modifier/AdvancedPricing.php | 54 +++++-------------- 3 files changed, 19 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index c866ee8895d..662e35a99c2 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -87,8 +87,8 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme { if (empty($this->_getExtensionAttributes())) { $this->setExtensionAttributes( - ObjectManager::getInstance()->get('\Magento\Framework\Api\ExtensionAttributesFactory') - ->create('Magento\Catalog\Api\Data\ProductTierPriceInterface') + ObjectManager::getInstance()->get(\Magento\Framework\Api\ExtensionAttributesFactory::class) + ->create(\Magento\Catalog\Api\Data\ProductTierPriceInterface::class) ); } return $this->_getExtensionAttributes(); diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index afe22b888b2..acb76ab1f3c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -15,6 +15,8 @@ use Magento\Customer\Model\GroupManagement; /** * Price Test + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class PriceTest extends \PHPUnit_Framework_TestCase { @@ -175,7 +177,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase // create sample TierPrice objects that would be coming from a REST call $tierPriceExtensionMock = $this->getMockBuilder(ProductTierPriceExtensionInterface::class) - ->setMethods(['getWebsiteId', 'getPercentageValue']) + ->setMethods(['getWebsiteId', 'setWebsiteId', 'getPercentageValue', 'setPercentageValue']) ->getMock(); $tierPriceExtensionMock->expects($this->any())->method('getWebsiteId')->willReturn($expectedWebsiteId); $tierPriceExtensionMock->expects($this->any())->method('getPercentageValue')->willReturn(null); @@ -218,7 +220,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase } $tierPriceExtention = $this->getMockBuilder(ProductTierPriceExtensionInterface::class) - ->setMethods(['getWebsiteId', 'getPercentageValue', 'setWebsiteId']) + ->setMethods(['getWebsiteId', 'setWebsiteId', 'getPercentageValue', 'setPercentageValue']) ->getMock(); $tierPriceExtention->expects($this->any())->method('getPercentageValue')->willReturn(50); $tierPriceExtention->expects($this->any())->method('setWebsiteId'); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index a01d5bcf546..062549f44bc 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -141,40 +141,12 @@ class AdvancedPricing extends AbstractModifier return $data; } - /** - * Prepare price fields - * - * Add currency symbol and validation - * - * @param string $fieldCode - * @return $this - */ - protected function preparePriceFields($fieldCode) - { - $pricePath = $this->arrayManager->findPath($fieldCode, $this->meta, null, 'children'); - - if ($pricePath) { - $this->meta = $this->arrayManager->set( - $pricePath . '/arguments/data/config/addbefore', - $this->meta, - $this->getStore()->getBaseCurrency()->getCurrencySymbol() - ); - $this->meta = $this->arrayManager->merge( - $pricePath . '/arguments/data/config', - $this->meta, - ['validation' => ['validate-zero-or-greater' => true]] - ); - } - - return $this; - } - /** * Customize tier price field * * @return $this */ - protected function customizeTierPrice() + private function customizeTierPrice() { $tierPricePath = $this->arrayManager->findPath( ProductAttributeInterface::CODE_TIER_PRICE, @@ -209,7 +181,7 @@ class AdvancedPricing extends AbstractModifier * * @return array */ - protected function getCustomerGroups() + private function getCustomerGroups() { if (!$this->moduleManager->isEnabled('Magento_Customer')) { return []; @@ -238,7 +210,7 @@ class AdvancedPricing extends AbstractModifier * * @return bool */ - protected function isScopeGlobal() + private function isScopeGlobal() { return $this->locator->getProduct() ->getResource() @@ -251,7 +223,7 @@ class AdvancedPricing extends AbstractModifier * * @return array */ - protected function getWebsites() + private function getWebsites() { $websites = [ [ @@ -292,7 +264,7 @@ class AdvancedPricing extends AbstractModifier * * @return int */ - protected function getDefaultCustomerGroup() + private function getDefaultCustomerGroup() { return $this->groupManagement->getAllCustomersGroup()->getId(); } @@ -316,7 +288,7 @@ class AdvancedPricing extends AbstractModifier * * @return bool */ - protected function isShowWebsiteColumn() + private function isShowWebsiteColumn() { if ($this->isScopeGlobal() || $this->storeManager->isSingleStoreMode()) { return false; @@ -329,7 +301,7 @@ class AdvancedPricing extends AbstractModifier * * @return bool */ - protected function isMultiWebsites() + private function isMultiWebsites() { return !$this->storeManager->isSingleStoreMode(); } @@ -339,7 +311,7 @@ class AdvancedPricing extends AbstractModifier * * @return bool */ - protected function isAllowChangeWebsite() + private function isAllowChangeWebsite() { if (!$this->isShowWebsiteColumn() || $this->locator->getProduct()->getStoreId()) { return false; @@ -352,7 +324,7 @@ class AdvancedPricing extends AbstractModifier * * @return $this */ - protected function addAdvancedPriceLink() + private function addAdvancedPriceLink() { $pricePath = $this->arrayManager->findPath( ProductAttributeInterface::CODE_PRICE, @@ -405,7 +377,7 @@ class AdvancedPricing extends AbstractModifier * @return array * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - protected function getTierPriceStructure($tierPricePath) + private function getTierPriceStructure($tierPricePath) { return [ 'arguments' => [ @@ -542,7 +514,7 @@ class AdvancedPricing extends AbstractModifier * * @return $this */ - protected function specialPriceDataToInline() + private function specialPriceDataToInline() { $pathFrom = $this->arrayManager->findPath('special_from_date', $this->meta, null, 'children'); $pathTo = $this->arrayManager->findPath('special_to_date', $this->meta, null, 'children'); @@ -598,7 +570,7 @@ class AdvancedPricing extends AbstractModifier * * @return $this */ - protected function customizeAdvancedPricing() + private function customizeAdvancedPricing() { $this->meta['advanced-pricing']['arguments']['data']['config']['opened'] = true; $this->meta['advanced-pricing']['arguments']['data']['config']['collapsible'] = false; @@ -657,7 +629,7 @@ class AdvancedPricing extends AbstractModifier * * @return \Magento\Store\Model\Store */ - protected function getStore() + private function getStore() { return $this->locator->getStore(); } -- GitLab From e260ac9bfd292b7c2c837b22fc7e8ae1b74bc1ec Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 22 Aug 2016 17:54:39 +0300 Subject: [PATCH 592/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Plugin/ProductRepositorySave.php | 3 --- .../Unit/Model/Plugin/ProductRepositorySaveTest.php | 10 +++++++--- app/code/Magento/ConfigurableProduct/etc/di.xml | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php index 0c25b4633c4..cfcb5e41799 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php +++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php @@ -14,9 +14,6 @@ use Magento\ConfigurableProduct\Api\Data\OptionInterface; use Magento\Catalog\Api\ProductAttributeRepositoryInterface; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -/** - * Class ProductRepositorySave - */ class ProductRepositorySave { /** diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php index ce3323dae06..3b2069296db 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/ProductRepositorySaveTest.php @@ -14,6 +14,7 @@ use Magento\ConfigurableProduct\Api\Data\OptionInterface; use Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** @@ -97,9 +98,12 @@ class ProductRepositorySaveTest extends \PHPUnit_Framework_TestCase $this->option = $this->getMockForAbstractClass(OptionInterface::class); - $this->plugin = new ProductRepositorySave( - $this->productAttributeRepository, - $this->productFactory + $this->plugin = (new ObjectManager($this))->getObject( + ProductRepositorySave::class, + [ + 'productAttributeRepository' => $this->productAttributeRepository, + 'productFactory' => $this->productFactory + ] ); } diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml index f661709a735..c3be4aaea18 100644 --- a/app/code/Magento/ConfigurableProduct/etc/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/di.xml @@ -59,7 +59,7 @@ </arguments> </type> <type name="Magento\Catalog\Api\ProductRepositoryInterface"> - <plugin name="configurableProductSaveOptions" sortOrder="10" type="\Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave"/> + <plugin name="configurableProductSaveOptions" sortOrder="10" type="Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave"/> </type> <type name="Magento\Catalog\Model\Product"> <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" /> -- GitLab From 943c610fe2ca293598890ec6e3dac72ada4617c6 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 22 Aug 2016 17:59:15 +0300 Subject: [PATCH 593/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Customer/Test/Unit/Controller/Plugin/AccountTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php index c1111bd8dea..b9c05d4005b 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Plugin/AccountTest.php @@ -177,7 +177,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase Account::class, [ 'session' => $this->session, - ['testaction'] + 'allowedActions' => ['testaction'] ] ); $this->assertSame( -- GitLab From 380ec0ca2ecd3f88abbcbebde5595b127f9c51d0 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Mon, 22 Aug 2016 10:12:55 -0500 Subject: [PATCH 594/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - Feedback from CR --- .../app/Magento/Config/Test/Block/System/Config/AdminForm.php | 2 +- .../Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php index f694e93689d..38bb261cb79 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Block/System/Config/AdminForm.php @@ -15,7 +15,7 @@ use Magento\Mtf\Client\Locator; */ class AdminForm extends Form { - protected $adminAccountSharingField = "#admin_security_admin_account_sharing"; + private $adminAccountSharingField = '#admin_security_admin_account_sharing'; public function adminAccountSharingAvailability() { diff --git a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php index 110fdada800..8cd455b6bed 100644 --- a/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php +++ b/dev/tests/functional/tests/app/Magento/Email/Test/Block/Adminhtml/Template/Edit/TemplateForm.php @@ -14,7 +14,7 @@ use Magento\Mtf\Client\Locator; */ class TemplateForm extends Form { - private $loadButton = "#load"; + private $loadButton = '#load'; /** * @return void -- GitLab From 1de0edc400e7088e6840aa9e0baf813e080b9a04 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Mon, 22 Aug 2016 10:19:51 -0500 Subject: [PATCH 595/838] MAGETWO-50123: Unable to assign blank value to attribute #3545 #4910 #5485 #5225 - fix integration test --- .../Product/Form/Modifier/_files/eav_expected_meta_output.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php index 2f2512d8e9e..29b092177b5 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/_files/eav_expected_meta_output.php @@ -35,7 +35,6 @@ return [ "visible" => "1", "required" => "0", "label" => "Enable Product", - "default" => null, "source" => "product-details", "scopeLabel" => "[WEBSITE]", "globalScope" => false, -- GitLab From 747d409e688b386a5c8b28f0983dd0e3b0c29a9c Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 22 Aug 2016 19:27:27 +0300 Subject: [PATCH 596/838] MAGETWO-56826: Notification messages area. Bug fixing activities --- .../adminhtml/ui_component/notification_area.xml | 2 +- .../web/css/source/_module.less | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml b/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml index 8a8cdb40b5e..e0149fff714 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml +++ b/app/code/Magento/AdminNotification/view/adminhtml/ui_component/notification_area.xml @@ -44,7 +44,7 @@ <item name="label" xsi:type="string" translate="true"/> <item name="dataType" xsi:type="string">text</item> <item name="sorting" xsi:type="string">asc</item> - <item name="sortOrder" xsi:type="number">10</item> + <item name="sortOrder" xsi:type="number">30</item> </item> </argument> </column> diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index 6dde9aa3bcc..e753eaa8650 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -35,7 +35,7 @@ } .message { - display: inline-block; + background: none; margin: 0 0 -3px; overflow: hidden; padding: @message-system-short-message__padding-vertical 0 @message-system-short-message__padding-vertical 3.3rem; @@ -46,13 +46,17 @@ } .action-menu-item { - &.action-close { + &.action-close-wrapper { + width: 3.5rem; + } + + .action-close { float: right; } - display: inline-block; - vertical-align: top; + float: right; padding: @message-system-short-message__padding-vertical 0 0; + vertical-align: top; } } @@ -72,7 +76,7 @@ .message-system-short { min-height: @message-system-short-wrapper__height; - .action-close { + .action-close-wrapper { display: none; } } -- GitLab From 8ba51d941e2d6a2c19c849680018ac6460885680 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Mon, 22 Aug 2016 11:37:20 -0500 Subject: [PATCH 597/838] MAGETWO-56197: Write functional test for MAGETWO-47822 - Fix grammar. --- .../Config/Test/Constraint/AssertAdminAccountSharing.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php index 2e6d41a99d3..ae01915bef3 100644 --- a/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php +++ b/dev/tests/functional/tests/app/Magento/Config/Test/Constraint/AssertAdminAccountSharing.php @@ -33,6 +33,6 @@ class AssertAdminAccountSharing extends AbstractConstraint */ public function toString() { - return 'Admin account sharing is available is present in in Stores>Configuration>advanced>admin grid.'; + return 'Admin Account Sharing option is available and present in Stores>Configuration>Advanced>Admin Grid.'; } } -- GitLab From 403ffb5159b9e5cc8234e9facccf87f4f71b3148 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 23 Aug 2016 10:17:30 +0300 Subject: [PATCH 598/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Model/Category/Plugin/StorageTest.php | 3 +++ .../Option/Plugin/ConfigurableProductTest.php | 23 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php index d74e3c81e5c..21ab961dcbd 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/StorageTest.php @@ -14,6 +14,9 @@ use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\CatalogUrlRewrite\Model\Category\Product; use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\Product as ProductResourceModel; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class StorageTest extends \PHPUnit_Framework_TestCase { /** diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php index fb619395e7a..6b162bbde85 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/Option/Plugin/ConfigurableProductTest.php @@ -5,6 +5,9 @@ */ namespace Magento\ConfigurableProduct\Test\Unit\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin; +use \Magento\ConfigurableProduct\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin\ConfigurableProduct + as InitializerOptionPlugin; + class ConfigurableProductTest extends \PHPUnit_Framework_TestCase { /** @@ -22,24 +25,36 @@ class ConfigurableProductTest extends \PHPUnit_Framework_TestCase ); $quoteItemMock = $this->getMock( - \Magento\Quote\Model\Quote\Item::class, ['getProductType', '__wakeup'], [], '', false + \Magento\Quote\Model\Quote\Item::class, + ['getProductType', '__wakeup'], + [], + '', + false ); $quoteItemMock->expects($this->once()) ->method('getProductType') ->will($this->returnValue($data['product_type'])); $stockItemMock = $this->getMock( - \Magento\CatalogInventory\Model\Stock\Item::class, ['setProductName', '__wakeup'], [], '', false + \Magento\CatalogInventory\Model\Stock\Item::class, + ['setProductName', '__wakeup'], + [], + '', + false ); $matcherMethod = $data['matcher_method']; $stockItemMock->expects($this->$matcherMethod()) ->method('setProductName'); $optionMock = $this->getMock( - \Magento\Quote\Model\Quote\Item\Option::class, ['getProduct', '__wakeup'], [], '', false + \Magento\Quote\Model\Quote\Item\Option::class, + ['getProduct', '__wakeup'], + [], + '', + false ); - $model = new \Magento\ConfigurableProduct\Model\Quote\Item\QuantityValidator\Initializer\Option\Plugin\ConfigurableProduct(); + $model = new InitializerOptionPlugin(); $model->afterGetStockItem($subjectMock, $stockItemMock, $optionMock, $quoteItemMock, 0); } -- GitLab From 7d1003b9f5a6cd5aa8f3ced9105492983ac9fcec Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 23 Aug 2016 10:34:26 +0300 Subject: [PATCH 599/838] MAGETWO-56702: Around plugins refactoring: refactoring and unit test fixing/coverage --- .../Unit/Controller/Adminhtml/Product/Builder/PluginTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php index bc4f156cd8f..e6c13a23541 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Controller/Adminhtml/Product/Builder/PluginTest.php @@ -71,7 +71,6 @@ class PluginTest extends \PHPUnit_Framework_TestCase $this->requestMock = $this->getMock(\Magento\Framework\App\Request\Http::class, [], [], '', false); $methods = ['setTypeId', 'getAttributes', 'addData', 'setWebsiteIds', '__wakeup']; $this->productMock = $this->getMock(\Magento\Catalog\Model\Product::class, $methods, [], '', false); - $product = $this->productMock; $attributeMethods = [ 'getId', 'getFrontend', -- GitLab From cb1462a72bab97f22d9ca46f2711117864799717 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Tue, 23 Aug 2016 10:49:38 +0300 Subject: [PATCH 600/838] MAGETWO-57227: Payments configuration sections default setting are wrong --- app/code/Magento/Paypal/etc/adminhtml/system.xml | 4 ++-- app/code/Magento/Paypal/view/adminhtml/web/styles.css | 4 +++- .../Model/Config/Structure/Reader/_files/actual/config.xml | 4 ++-- .../Model/Config/Structure/Reader/_files/expected/config.xml | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Paypal/etc/adminhtml/system.xml b/app/code/Magento/Paypal/etc/adminhtml/system.xml index 68fe46bc258..c4fe3def36c 100644 --- a/app/code/Magento/Paypal/etc/adminhtml/system.xml +++ b/app/code/Magento/Paypal/etc/adminhtml/system.xml @@ -28,12 +28,12 @@ <group id="other_paypal_payment_solutions" translate="label" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Other PayPal Payment Solutions:</label> <fieldset_css>paypal-top-section paypal-other-header</fieldset_css> - <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> + <frontend_model>\Magento\Config\Block\System\Config\Form\Fieldset</frontend_model> </group> <group id="other_payment_methods" translate="label" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Other Payment Methods:</label> <fieldset_css>paypal-top-section payments-other-header</fieldset_css> - <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> + <frontend_model>\Magento\Config\Block\System\Config\Form\Fieldset</frontend_model> </group> </section> <section id="payment_all_paypal" showInDefault="0" showInWebsite="0" showInStore="0"> diff --git a/app/code/Magento/Paypal/view/adminhtml/web/styles.css b/app/code/Magento/Paypal/view/adminhtml/web/styles.css index 511623e1f59..456a6aff73c 100644 --- a/app/code/Magento/Paypal/view/adminhtml/web/styles.css +++ b/app/code/Magento/Paypal/view/adminhtml/web/styles.css @@ -30,4 +30,6 @@ .paypal-other-header > .admin__collapsible-block > a.open::before {content: "\25B2" !important;} .paypal-other-header > .admin__collapsible-block > a::before {color: #000; content: "\25BC" !important; font-size: 1rem; top: 2.2rem;} .paypal-other-header > .admin__collapsible-block > a {color: #007bdb !important; text-align: right;} -.payments-other-header > .admin__collapsible-block > a::before {content: "" !important;} \ No newline at end of file +.payments-other-header > .admin__collapsible-block > a {display: inline-block;} +.payments-other-header > .admin__collapsible-block > a::before {content: "\25BC" !important; font-size: 1rem;} +.payments-other-header > .admin__collapsible-block > a.open::before {content: "\25B2" !important;} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/actual/config.xml b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/actual/config.xml index 6a607e45b68..6d77816d262 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/actual/config.xml +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/actual/config.xml @@ -28,12 +28,12 @@ <group id="other_paypal_payment_solutions" translate="label" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Other PayPal Payment Solutions:</label> <fieldset_css>paypal-top-section paypal-other-header</fieldset_css> - <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> + <frontend_model>\Magento\Config\Block\System\Config\Form\Fieldset</frontend_model> </group> <group id="other_payment_methods" translate="label" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Other Payment Methods:</label> <fieldset_css>paypal-top-section payments-other-header</fieldset_css> - <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> + <frontend_model>\Magento\Config\Block\System\Config\Form\Fieldset</frontend_model> </group> </section> <section id="payment_all_paypal" showInDefault="0" showInWebsite="0" showInStore="0"> diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml index 9dc77b83665..40bf9602edb 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml +++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/Config/Structure/Reader/_files/expected/config.xml @@ -28,12 +28,12 @@ <group id="other_paypal_payment_solutions" translate="label" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Other PayPal Payment Solutions:</label> <fieldset_css>paypal-top-section paypal-other-header</fieldset_css> - <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> + <frontend_model>\Magento\Config\Block\System\Config\Form\Fieldset</frontend_model> </group> <group id="other_payment_methods" translate="label" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Other Payment Methods:</label> <fieldset_css>paypal-top-section payments-other-header</fieldset_css> - <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model> + <frontend_model>\Magento\Config\Block\System\Config\Form\Fieldset</frontend_model> </group> </section> <section id="payment_all_paypal" showInDefault="0" showInWebsite="0" showInStore="0"> -- GitLab From 475a80ee9a4776d022512759936290f66bb42a41 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 10:26:02 +0300 Subject: [PATCH 601/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55256: Schema upgrade --- .../Api/Data/ProductTierPriceInterface.php | 31 ++++++++++++++++++ .../Catalog/Model/Product/TierPrice.php | 32 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php index d5b354da1ea..6465458d7ca 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php @@ -18,8 +18,12 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface const VALUE = 'value'; + const PERCENTAGE_VALUE = 'percentage_value'; + const CUSTOMER_GROUP_ID = 'customer_group_id'; + const WEBSITE_ID = 'website_id'; + /** * Retrieve customer group id * @@ -65,6 +69,33 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface */ public function setValue($value); + /** + * Retrieve percentage value + * @return float + */ + public function getPercentageValue(); + + /** + * Set percentage value + * + * @param $value + * @return $this + */ + public function setPercentageValue($value); + + /** + * Retrieve website id + * @return int + */ + public function getWebsiteId(); + + /** + * Set website id + * @param int $websiteId + * @return $this + */ + public function setWebsiteId($websiteId); + /** * Retrieve existing extension attributes object. * diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 662e35a99c2..bd137090167 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -57,6 +57,38 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme return $this->setData(self::VALUE, $value); } + /** + * @inheritdoc + */ + public function getPercentageValue() + { + return $this->getData(self::PERCENTAGE_VALUE); + } + + /** + * @inheritdoc + */ + public function setPercentageValue($value) + { + return $this->setData(self::PERCENTAGE_VALUE, $value); + } + + /** + * @inheritdoc + */ + public function setWebsiteId($websiteId) + { + return $this->setData(self::WEBSITE_ID, $websiteId); + } + + /** + * @inheritdoc + */ + public function getWebsiteId() + { + return $this->getData(self::WEBSITE_ID); + } + /** * Retrieve customer group id * -- GitLab From 40cda386bf93530868cd7d63a627b19a3c54077a Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 12 Jul 2016 12:54:13 +0300 Subject: [PATCH 602/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55256: Schema upgrade --- .../Magento/Catalog/Api/ProductRepositoryInterfaceTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index f30c1bffa00..6436cd60273 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -888,11 +888,15 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup1, 'value' => 3.14, 'qty' => 5, + 'percentageValue' => 0, + 'websiteId' => 1, ], [ 'customer_group_id' => $custGroup2, 'value' => 3.45, 'qty' => 10, + 'percentageValue' => 0, + 'websiteId' => 1, ] ]; $this->saveProduct($productData); @@ -917,6 +921,8 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup3, 'value' => 2.10, 'qty' => 12, + 'percentageValue' => 0, + 'websiteId' => 1, ]; $response[self::KEY_TIER_PRICES] = $tierPrices; $response = $this->updateProduct($response); -- GitLab From b018071436ce184520f9a19a1f47623db77d83bb Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 10:31:49 +0300 Subject: [PATCH 603/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../Api/Data/ProductTierPriceInterface.php | 31 ------------------ .../Catalog/Model/Product/TierPrice.php | 32 ------------------- .../Catalog/Model/Product/Type/Price.php | 2 +- .../Api/ProductRepositoryInterfaceTest.php | 6 ---- 4 files changed, 1 insertion(+), 70 deletions(-) diff --git a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php index 6465458d7ca..d5b354da1ea 100644 --- a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php +++ b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php @@ -18,12 +18,8 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface const VALUE = 'value'; - const PERCENTAGE_VALUE = 'percentage_value'; - const CUSTOMER_GROUP_ID = 'customer_group_id'; - const WEBSITE_ID = 'website_id'; - /** * Retrieve customer group id * @@ -69,33 +65,6 @@ interface ProductTierPriceInterface extends ExtensibleDataInterface */ public function setValue($value); - /** - * Retrieve percentage value - * @return float - */ - public function getPercentageValue(); - - /** - * Set percentage value - * - * @param $value - * @return $this - */ - public function setPercentageValue($value); - - /** - * Retrieve website id - * @return int - */ - public function getWebsiteId(); - - /** - * Set website id - * @param int $websiteId - * @return $this - */ - public function setWebsiteId($websiteId); - /** * Retrieve existing extension attributes object. * diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index bd137090167..662e35a99c2 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -57,38 +57,6 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme return $this->setData(self::VALUE, $value); } - /** - * @inheritdoc - */ - public function getPercentageValue() - { - return $this->getData(self::PERCENTAGE_VALUE); - } - - /** - * @inheritdoc - */ - public function setPercentageValue($value) - { - return $this->setData(self::PERCENTAGE_VALUE, $value); - } - - /** - * @inheritdoc - */ - public function setWebsiteId($websiteId) - { - return $this->setData(self::WEBSITE_ID, $websiteId); - } - - /** - * @inheritdoc - */ - public function getWebsiteId() - { - return $this->getData(self::WEBSITE_ID); - } - /** * Retrieve customer group id * diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index af15e049203..9fba18effe1 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -418,7 +418,7 @@ class Price ? $extensionAttributes->getWebsiteId() : $websiteId; $prices[] = [ - 'website_id' => $websiteId, + 'website_id' => $price->getExtensionAttributes()->getWebsiteId(), 'cust_group' => $price->getCustomerGroupId(), 'website_price' => $price->getValue(), 'price' => $price->getValue(), diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 6436cd60273..f30c1bffa00 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -888,15 +888,11 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup1, 'value' => 3.14, 'qty' => 5, - 'percentageValue' => 0, - 'websiteId' => 1, ], [ 'customer_group_id' => $custGroup2, 'value' => 3.45, 'qty' => 10, - 'percentageValue' => 0, - 'websiteId' => 1, ] ]; $this->saveProduct($productData); @@ -921,8 +917,6 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract 'customer_group_id' => $custGroup3, 'value' => 2.10, 'qty' => 12, - 'percentageValue' => 0, - 'websiteId' => 1, ]; $response[self::KEY_TIER_PRICES] = $tierPrices; $response = $this->updateProduct($response); -- GitLab From 74fc1288f95a2ddac9a7cb7531df8b093b0a385a Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 10:33:51 +0300 Subject: [PATCH 604/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../Product/Attribute/Backend/Tierprice.php | 21 ++++++++++++ .../Catalog/Model/Product/Type/Price.php | 2 +- .../Magento/Catalog/_files/product_simple.php | 32 +++++++++++++++++++ 3 files changed, 54 insertions(+), 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 480f8e8942e..b2d4bbcdf23 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -202,4 +202,25 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr ? $priceRow['percentage_value'] : null; } + + /** + * @inheritdoc + */ + public function validate($object) + { + $attribute = $this->getAttribute(); + $priceRows = $object->getData($attribute->getName()); + $priceRows = array_filter((array)$priceRows); + + foreach ($priceRows as $priceRow) { + $percentage = isset($priceRow['percentage_value']) ? $priceRow['percentage_value'] : 0 ; + if (!is_numeric($percentage) || $percentage < 0 || $percentage > 100) { + throw new \Magento\Framework\Exception\LocalizedException( + __('Percentage value must be a number between 0 and 100.') + ); + } + } + + return parent::validate($object); + } } diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index 9fba18effe1..b4f8173d524 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -418,7 +418,7 @@ class Price ? $extensionAttributes->getWebsiteId() : $websiteId; $prices[] = [ - 'website_id' => $price->getExtensionAttributes()->getWebsiteId(), + 'website_id' => $extensionAttributes ? $extensionAttributes->getWebsiteId() : $websiteId, 'cust_group' => $price->getCustomerGroupId(), 'website_price' => $price->getValue(), 'price' => $price->getValue(), diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 63b7a28b50b..7cbc311129b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -57,6 +57,38 @@ $tierPrices[] = $tierPriceFactory->create( ] )->setExtensionAttributes($tpExtensionAttributes); +$tierPrices = []; +/** @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory */ +$tierPriceFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 2, + 'value' => 8 + ] + ] +); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 5, + 'value' => 5 + ] + ] +); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, + 'qty' => 3, + 'value' => 0, + 'percentage_value' => 50 + ] + ] +); + /** @var $product \Magento\Catalog\Model\Product */ $product = $objectManager->create(\Magento\Catalog\Model\Product::class); $product->isObjectNew(true); -- GitLab From 7e22889e95721a22406d22ebaf315d3e9181b2bc Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Fri, 15 Jul 2016 14:04:32 +0300 Subject: [PATCH 605/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55259: Update Product PriceModel --- .../Magento/Catalog/_files/product_simple.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 7cbc311129b..cb32bb87185 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -83,7 +83,15 @@ $tierPrices[] = $tierPriceFactory->create( 'data' => [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, 'qty' => 3, - 'value' => 0, + 'value' => 5 + ] + ] +); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, + 'qty' => 10, 'percentage_value' => 50 ] ] -- GitLab From d606efe6fe74e4a5d4bfc1edde9da46e296b8a14 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 10:37:29 +0300 Subject: [PATCH 606/838] MAGETWO-55261: Update Advanced Pricing Popup on product page - tierprice fixes --- .../Product/Attribute/Backend/Tierprice.php | 21 ------------------- 1 file changed, 21 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 b2d4bbcdf23..480f8e8942e 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -202,25 +202,4 @@ class Tierprice extends \Magento\Catalog\Model\Product\Attribute\Backend\GroupPr ? $priceRow['percentage_value'] : null; } - - /** - * @inheritdoc - */ - public function validate($object) - { - $attribute = $this->getAttribute(); - $priceRows = $object->getData($attribute->getName()); - $priceRows = array_filter((array)$priceRows); - - foreach ($priceRows as $priceRow) { - $percentage = isset($priceRow['percentage_value']) ? $priceRow['percentage_value'] : 0 ; - if (!is_numeric($percentage) || $percentage < 0 || $percentage > 100) { - throw new \Magento\Framework\Exception\LocalizedException( - __('Percentage value must be a number between 0 and 100.') - ); - } - } - - return parent::validate($object); - } } -- GitLab From 83bdcafcf3d99c43da4f93b4fa62c8e0a95475bc Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 10:47:16 +0300 Subject: [PATCH 607/838] MAGETWO-49543: Using Percentage Discount for Tier Prices - MAGETWO-55521: Save price data --- app/code/Magento/Catalog/Model/Product/TierPrice.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 662e35a99c2..985853314c4 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -80,8 +80,6 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme /** * {@inheritdoc} - * - * @return \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface|null */ public function getExtensionAttributes() { @@ -96,9 +94,6 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme /** * {@inheritdoc} - * - * @param \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface $extensionAttributes - * @return $this */ public function setExtensionAttributes( \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface $extensionAttributes -- GitLab From 382d479cba705fdccdc853803ed2e5f4b769cff4 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Fri, 29 Jul 2016 17:36:50 +0300 Subject: [PATCH 608/838] MAGETWO-49542: Managing Tier Prices - MAGETWO-55966: Add "Tier Price" column to Pricing grid --- .../ConfigurableProduct/Setup/InstallData.php | 1 - .../ConfigurableProduct/Setup/UpgradeData.php | 65 +++++++++++++++++++ .../ConfigurableProduct/etc/module.xml | 2 +- 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php diff --git a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php index de19f2b1ff1..a4b0757738e 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php @@ -51,7 +51,6 @@ class InstallData implements InstallDataInterface 'special_price', 'special_from_date', 'special_to_date', - 'tier_price', 'weight', 'color' ]; diff --git a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php new file mode 100644 index 00000000000..06c2075a7c4 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\ConfigurableProduct\Setup; + +use Magento\ConfigurableProduct\Model\Product\Type\Configurable; +use Magento\Framework\Setup\UpgradeDataInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Eav\Setup\EavSetup; +use Magento\Eav\Setup\EavSetupFactory; + +/** + * Upgrade Data script + * @codeCoverageIgnore + */ +class UpgradeData implements UpgradeDataInterface +{ + /** + * EAV setup factory + * + * @var EavSetupFactory + */ + private $eavSetupFactory; + + /** + * Init + * + * @param EavSetupFactory $eavSetupFactory + */ + public function __construct(EavSetupFactory $eavSetupFactory) + { + $this->eavSetupFactory = $eavSetupFactory; + } + + /** + * {@inheritdoc} + */ + public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) + { + $setup->startSetup(); + if (version_compare($context->getVersion(), '2.2.0') < 0) { + /** @var EavSetup $eavSetup */ + $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]); + $relatedProductTypes = explode( + ',', + $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'tier_price', 'apply_to') + ); + $key = array_search(Configurable::TYPE_CODE, $relatedProductTypes); + if($key !== false) { + unset($relatedProductTypes[$key]); + $eavSetup->updateAttribute( + \Magento\Catalog\Model\Product::ENTITY, + 'tier_price', + 'apply_to', + implode(',', $relatedProductTypes) + ); + } + } + + $setup->endSetup(); + } +} diff --git a/app/code/Magento/ConfigurableProduct/etc/module.xml b/app/code/Magento/ConfigurableProduct/etc/module.xml index 8a64e9f026d..706338092c4 100644 --- a/app/code/Magento/ConfigurableProduct/etc/module.xml +++ b/app/code/Magento/ConfigurableProduct/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_ConfigurableProduct" setup_version="2.0.0"> + <module name="Magento_ConfigurableProduct" setup_version="2.2.0"> <sequence> <module name="Magento_Catalog"/> <module name="Magento_Msrp"/> -- GitLab From 1aef59d991a2e4e61a92f98a30f78d68e481d8b2 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 1 Aug 2016 10:44:23 +0300 Subject: [PATCH 609/838] MAGETWO-49542: Managing Tier Prices - MAGETWO-55966: Add "Tier Price" column to Pricing grid --- app/code/Magento/ConfigurableProduct/Setup/InstallData.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php index a4b0757738e..de19f2b1ff1 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/InstallData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/InstallData.php @@ -51,6 +51,7 @@ class InstallData implements InstallDataInterface 'special_price', 'special_from_date', 'special_to_date', + 'tier_price', 'weight', 'color' ]; -- GitLab From c1e4d4a225cf04c75b7d22efdb1dc83adfcae68e Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 1 Aug 2016 11:29:45 +0300 Subject: [PATCH 610/838] MAGETWO-49542: Managing Tier Prices - MAGETWO-55966: Add "Tier Price" column to Pricing grid --- app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php index 06c2075a7c4..4c321f521bb 100644 --- a/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php +++ b/app/code/Magento/ConfigurableProduct/Setup/UpgradeData.php @@ -49,7 +49,7 @@ class UpgradeData implements UpgradeDataInterface $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'tier_price', 'apply_to') ); $key = array_search(Configurable::TYPE_CODE, $relatedProductTypes); - if($key !== false) { + if ($key !== false) { unset($relatedProductTypes[$key]); $eavSetup->updateAttribute( \Magento\Catalog\Model\Product::ENTITY, -- GitLab From b71cf8f99cdf5f7335f621fa0c74f87a43337d65 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 26 Jul 2016 15:34:53 +0300 Subject: [PATCH 611/838] MAGETWO-49543: Using Percentage Discount for Tier Prices --- app/code/Magento/Catalog/Model/Product/Type/Price.php | 2 +- .../testsuite/Magento/Catalog/_files/product_simple.php | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index b4f8173d524..af15e049203 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -418,7 +418,7 @@ class Price ? $extensionAttributes->getWebsiteId() : $websiteId; $prices[] = [ - 'website_id' => $extensionAttributes ? $extensionAttributes->getWebsiteId() : $websiteId, + 'website_id' => $websiteId, 'cust_group' => $price->getCustomerGroupId(), 'website_price' => $price->getValue(), 'price' => $price->getValue(), diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index cb32bb87185..cd767abc37d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -87,15 +87,18 @@ $tierPrices[] = $tierPriceFactory->create( ] ] ); +/** @var $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->create(\Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory::class); +$tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); + $tierPrices[] = $tierPriceFactory->create( [ 'data' => [ 'customer_group_id' => \Magento\Customer\Model\Group::NOT_LOGGED_IN_ID, - 'qty' => 10, - 'percentage_value' => 50 + 'qty' => 10 ] ] -); +)->setExtensionAttributes($tpExtensionAttributes); /** @var $product \Magento\Catalog\Model\Product */ $product = $objectManager->create(\Magento\Catalog\Model\Product::class); -- GitLab From 40c78b327585382e248353f57d5d4ac83c102fd9 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Tue, 26 Jul 2016 18:15:44 +0300 Subject: [PATCH 612/838] MAGETWO-49543: Using Percentage Discount for Tier Prices --- .../testsuite/Magento/Catalog/_files/product_simple.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index cd767abc37d..aadf1e74a88 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -88,7 +88,7 @@ $tierPrices[] = $tierPriceFactory->create( ] ); /** @var $tpExtensionAttributes */ -$tpExtensionAttributesFactory = $objectManager->create(\Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory::class); +$tpExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); $tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); $tierPrices[] = $tierPriceFactory->create( -- GitLab From b20732d387fa8022084fe96f41941ac395d31328 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Mon, 1 Aug 2016 15:33:31 +0300 Subject: [PATCH 613/838] MAGETWO-55967: Slide out panel --- .../Ui/view/base/web/js/form/components/insert-form.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js b/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js index f68e322a49d..11643d075a7 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js @@ -38,7 +38,10 @@ define([ el.innerHTML = elem; actions = el.getElementsByClassName(actionsClass)[0]; - el.removeChild(actions); + + if (actions) { + el.removeChild(actions); + } return el.innerHTML; } -- GitLab From 09a991ecc1a40e3cc6b3a63ebc1efc933faa8454 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 11:09:13 +0300 Subject: [PATCH 614/838] MAGETWO-49542: Managing Tier Prices MAGETWO-55965: Integrate new CG component --- .../Product/Form/Modifier/AdvancedPricing.php | 15 +++- .../adminhtml/ui_component/product_form.xml | 2 +- .../Rule/CustomerGroupsOptionsProvider.php | 48 ------------ .../CustomerGroupsOptionsProviderTest.php | 73 ------------------- .../ui_component/catalog_rule_form.xml | 2 +- .../Customer/Model/Config/Source/Group.php | 19 ++++- .../Model/Customer/Attribute/Source/Group.php | 4 +- .../Customer/Model/Customer/Source/Group.php | 21 ++++-- ...oupSourceForLoggedInCustomersInterface.php | 14 ++++ .../Customer/Source/GroupSourceInterface.php | 14 ++++ .../GroupSourceWithAllGroupsInterface.php | 13 ++++ .../Source/GroupWithoutAllSources.php | 14 ++++ .../Unit/Model/Customer/Source/GroupTest.php | 6 +- app/code/Magento/Customer/etc/di.xml | 6 ++ 14 files changed, 114 insertions(+), 137 deletions(-) delete mode 100644 app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php delete mode 100644 app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php create mode 100644 app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php create mode 100644 app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php create mode 100644 app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php create mode 100644 app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 062549f44bc..37c4382ea05 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -7,7 +7,9 @@ namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Model\Locator\LocatorInterface; +use Magento\Customer\Model\Customer\Source\GroupSourceInterface; use Magento\Directory\Helper\Data; +use Magento\Framework\App\ObjectManager; use Magento\Store\Model\StoreManagerInterface; use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Api\GroupManagementInterface; @@ -80,6 +82,10 @@ class AdvancedPricing extends AbstractModifier * @var array */ protected $meta = []; + /** + * @var GroupSourceInterface + */ + private $customerGroupSource; /** * @param LocatorInterface $locator @@ -91,6 +97,7 @@ class AdvancedPricing extends AbstractModifier * @param Data $directoryHelper * @param ArrayManager $arrayManager * @param string $scopeName + * @param GroupSourceInterface $customerGroupSource * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -102,7 +109,8 @@ class AdvancedPricing extends AbstractModifier ModuleManager $moduleManager, Data $directoryHelper, ArrayManager $arrayManager, - $scopeName = '' + $scopeName = '', + GroupSourceInterface $customerGroupSource = null ) { $this->locator = $locator; $this->storeManager = $storeManager; @@ -113,6 +121,8 @@ class AdvancedPricing extends AbstractModifier $this->directoryHelper = $directoryHelper; $this->arrayManager = $arrayManager; $this->scopeName = $scopeName; + $this->customerGroupSource = $customerGroupSource + ?: ObjectManager::getInstance()->get(GroupSourceInterface::class); } /** @@ -186,6 +196,9 @@ class AdvancedPricing extends AbstractModifier if (!$this->moduleManager->isEnabled('Magento_Customer')) { return []; } + + return $this->customerGroupSource->toOptionArray(); + $customerGroups = [ [ 'label' => __('ALL GROUPS'), diff --git a/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml b/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml index 362aac7c8cf..64e0d2ec59d 100644 --- a/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml +++ b/app/code/Magento/CatalogInventory/view/adminhtml/ui_component/product_form.xml @@ -242,7 +242,7 @@ </argument> <field name="customer_group_id"> <argument name="data" xsi:type="array"> - <item name="options" xsi:type="object">Magento\Customer\Model\Customer\Source\Group</item> + <item name="options" xsi:type="object">Magento\Customer\Model\Customer\Source\GroupSourceInterface</item> <item name="config" xsi:type="array"> <item name="dataType" xsi:type="string">text</item> <item name="formElement" xsi:type="string">select</item> diff --git a/app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php b/app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php deleted file mode 100644 index ebc0747d83a..00000000000 --- a/app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\CatalogRule\Model\Rule; - -class CustomerGroupsOptionsProvider implements \Magento\Framework\Data\OptionSourceInterface -{ - /** - * @var \Magento\Customer\Api\GroupRepositoryInterface - */ - private $groupRepository; - - /** - * @var \Magento\Framework\Api\SearchCriteriaBuilder - */ - private $searchCriteriaBuilder; - - /** - * @var \Magento\Framework\Convert\DataObject - */ - private $objectConverter; - - /** - * @param \Magento\Customer\Api\GroupRepositoryInterface $groupRepository - * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder - * @param \Magento\Framework\Convert\DataObject $objectConverter - */ - public function __construct( - \Magento\Customer\Api\GroupRepositoryInterface $groupRepository, - \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, - \Magento\Framework\Convert\DataObject $objectConverter - ) { - $this->groupRepository = $groupRepository; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->objectConverter = $objectConverter; - } - - /** - * @return array - */ - public function toOptionArray() - { - $customerGroups = $this->groupRepository->getList($this->searchCriteriaBuilder->create())->getItems(); - return $this->objectConverter->toOptionArray($customerGroups, 'id', 'code'); - } -} diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php deleted file mode 100644 index 464857949a4..00000000000 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\CatalogRule\Test\Unit\Model\Rule; - -class CustomerGroupsOptionsProviderTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider - */ - private $model; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $groupRepositoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $searchCriteriaBuilderMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $objectConverterMock; - - protected function setup() - { - $this->groupRepositoryMock = $this->getMock(\Magento\Customer\Api\GroupRepositoryInterface::class); - $this->searchCriteriaBuilderMock = $this->getMock( - \Magento\Framework\Api\SearchCriteriaBuilder::class, - [], - [], - '', - false - ); - $this->objectConverterMock = $this->getMock(\Magento\Framework\Convert\DataObject::class, [], [], '', false); - $this->model = new \Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider( - $this->groupRepositoryMock, - $this->searchCriteriaBuilderMock, - $this->objectConverterMock - ); - } - - public function testToOptionArray() - { - $customerGroups = ['group1', 'group2']; - - $options = [ - ['label' => 'label', 'value' => 'value'] - ]; - - $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); - $searchResultMock = $this->getMock(\Magento\Customer\Api\Data\GroupSearchResultsInterface::class); - $this->searchCriteriaBuilderMock->expects($this->once())->method('create')->willReturn($searchCriteriaMock); - - $this->groupRepositoryMock->expects($this->once()) - ->method('getList') - ->with($searchCriteriaMock) - ->willReturn($searchResultMock); - - $searchResultMock->expects($this->once())->method('getItems')->willReturn($customerGroups); - $this->objectConverterMock->expects($this->once()) - ->method('toOptionArray') - ->with($customerGroups, 'id', 'code') - ->willReturn($options); - - $this->assertEquals($options, $this->model->toOptionArray()); - } -} diff --git a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml index 3aff6845746..af60e024716 100644 --- a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml +++ b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml @@ -149,7 +149,7 @@ <item name="source" xsi:type="string">catalog_rule</item> <item name="dataScope" xsi:type="string">customer_group_ids</item> </item> - <item name="options" xsi:type="object">Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider</item> + <item name="options" xsi:type="object">\Magento\Customer\Model\Customer\Source\GroupSourceInterface</item> </argument> </field> <field name="from_date"> diff --git a/app/code/Magento/Customer/Model/Config/Source/Group.php b/app/code/Magento/Customer/Model/Config/Source/Group.php index 40c7712f5aa..76f0b142da0 100644 --- a/app/code/Magento/Customer/Model/Config/Source/Group.php +++ b/app/code/Magento/Customer/Model/Config/Source/Group.php @@ -6,6 +6,8 @@ namespace Magento\Customer\Model\Config\Source; use Magento\Customer\Api\GroupManagementInterface; +use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; +use Magento\Framework\App\ObjectManager; class Group implements \Magento\Framework\Option\ArrayInterface { @@ -15,25 +17,36 @@ class Group implements \Magento\Framework\Option\ArrayInterface protected $_options; /** + * @deprecated * @var GroupManagementInterface */ protected $_groupManagement; /** + * @deprecated * @var \Magento\Framework\Convert\DataObject */ protected $_converter; + /** + * @var GroupSourceForLoggedInCustomersInterface + */ + private $groupSourceForLoggedInCustomers; + /** * @param GroupManagementInterface $groupManagement * @param \Magento\Framework\Convert\DataObject $converter + * @param GroupSourceForLoggedInCustomersInterface $groupSourceForLoggedInCustomers */ public function __construct( GroupManagementInterface $groupManagement, - \Magento\Framework\Convert\DataObject $converter + \Magento\Framework\Convert\DataObject $converter, + GroupSourceForLoggedInCustomersInterface $groupSourceForLoggedInCustomers = null ) { $this->_groupManagement = $groupManagement; $this->_converter = $converter; + $this->groupSourceForLoggedInCustomers = $groupSourceForLoggedInCustomers + ?: ObjectManager::getInstance()->get(GroupSourceForLoggedInCustomersInterface::class); } /** @@ -42,10 +55,10 @@ class Group implements \Magento\Framework\Option\ArrayInterface public function toOptionArray() { if (!$this->_options) { - $groups = $this->_groupManagement->getLoggedInGroups(); - $this->_options = $this->_converter->toOptionArray($groups, 'id', 'code'); + $this->_options = $this->groupSourceForLoggedInCustomers->toOptionArray(); array_unshift($this->_options, ['value' => '', 'label' => __('-- Please Select --')]); } + return $this->_options; } } diff --git a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php index 4663d26b628..22f196d0c2b 100644 --- a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php @@ -6,13 +6,14 @@ namespace Magento\Customer\Model\Customer\Attribute\Source; use Magento\Customer\Api\GroupManagementInterface; +use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; /** * Customer group attribute source * * @author Magento Core Team <core@magentocommerce.com> */ -class Group extends \Magento\Eav\Model\Entity\Attribute\Source\Table +class Group extends \Magento\Eav\Model\Entity\Attribute\Source\Table implements GroupSourceForLoggedInCustomersInterface { /** * @var GroupManagementInterface @@ -50,6 +51,7 @@ class Group extends \Magento\Eav\Model\Entity\Attribute\Source\Table $groups = $this->_groupManagement->getLoggedInGroups(); $this->_options = $this->_converter->toOptionArray($groups, 'id', 'code'); } + return $this->_options; } } diff --git a/app/code/Magento/Customer/Model/Customer/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Source/Group.php index 59dc3be52f1..068d960ea77 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Source/Group.php @@ -5,12 +5,13 @@ */ namespace Magento\Customer\Model\Customer\Source; +use Magento\Customer\Api\Data\GroupSearchResultsInterface; use Magento\Framework\Module\Manager as ModuleManager; use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -class Group implements \Magento\Framework\Option\ArrayInterface +class Group implements GroupSourceWithAllGroupsInterface { /** * @var ModuleManager @@ -27,6 +28,12 @@ class Group implements \Magento\Framework\Option\ArrayInterface */ protected $searchCriteriaBuilder; + /** + * Defines is 'ALL GROUPS' value should be added to options + * @var bool + */ + protected $isShowAllGroupsValue = true; + /** * @param ModuleManager $moduleManager * @param GroupRepositoryInterface $groupRepository @@ -52,14 +59,16 @@ class Group implements \Magento\Framework\Option\ArrayInterface if (!$this->moduleManager->isEnabled('Magento_Customer')) { return []; } - $customerGroups = [ - [ + $customerGroups = []; + + if ($this->isShowAllGroupsValue) { + $customerGroups[] = [ 'label' => __('ALL GROUPS'), 'value' => GroupInterface::CUST_GROUP_ALL, - ] - ]; + ]; + } - /** @var GroupInterface[] $groups */ + /** @var GroupSearchResultsInterface $groups */ $groups = $this->groupRepository->getList($this->searchCriteriaBuilder->create()); foreach ($groups->getItems() as $group) { $customerGroups[] = [ diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php new file mode 100644 index 00000000000..e71ecfdd50a --- /dev/null +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Customer\Model\Customer\Source; + +use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; + +interface GroupSourceForLoggedInCustomersInterface extends OptionArrayInterface +{ + +} \ No newline at end of file diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php new file mode 100644 index 00000000000..4e1fcf4a639 --- /dev/null +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Model\Customer\Source; + + +use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; + +interface GroupSourceInterface extends OptionArrayInterface +{ + +} \ No newline at end of file diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php new file mode 100644 index 00000000000..ef60c4cc995 --- /dev/null +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Model\Customer\Source; + +use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; + + +interface GroupSourceWithAllGroupsInterface extends OptionArrayInterface +{ +} \ No newline at end of file diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php new file mode 100644 index 00000000000..e90e57bdd6a --- /dev/null +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php @@ -0,0 +1,14 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Customer\Model\Customer\Source; + +use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; + +class GroupWithoutAllSources extends Group implements OptionArrayInterface +{ + protected $isShowAllGroupsValue = false; +} \ No newline at end of file diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php index d9ca3bdc1ba..1228d97ac57 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Customer\Test\Unit\Model\Customer\Source; -use Magento\Customer\Model\Customer\Source\Group; +use Magento\Customer\Model\Customer\Source\GroupSource; use Magento\Framework\Module\Manager; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -15,7 +15,7 @@ use Magento\Customer\Api\Data\GroupSearchResultsInterface; class GroupTest extends \PHPUnit_Framework_TestCase { /** - * @var Group + * @var GroupSource */ private $model; @@ -61,7 +61,7 @@ class GroupTest extends \PHPUnit_Framework_TestCase $this->searchResultMock = $this->getMockBuilder(GroupSearchResultsInterface::class) ->getMockForAbstractClass(); - $this->model = new Group( + $this->model = new GroupSource( $this->moduleManagerMock, $this->groupRepositoryMock, $this->searchCriteriaBuilderMock diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index d8f320161ab..5229a709ed4 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -51,6 +51,12 @@ type="Magento\Customer\Helper\View" /> <preference for="Magento\Customer\Model\Address\CustomAttributeListInterface" type="Magento\Customer\Model\Address\CustomAttributeList" /> + <preference for="Magento\Customer\Model\Customer\Source\GroupSourceWithAllGroupsInterface" + type="\Magento\Customer\Model\Customer\Source\Group" /> + <preference for="Magento\Customer\Model\Customer\Source\GroupSourceInterface" + type="\Magento\Customer\Model\Customer\Source\GroupWithoutAllSources" /> + <preference for="Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface" + type="\Magento\Customer\Model\Customer\Attribute\Source\Group"/> <type name="Magento\Customer\Model\Session"> <arguments> <argument name="configShare" xsi:type="object">Magento\Customer\Model\Config\Share\Proxy</argument> -- GitLab From 4421078b696946d0715ee75f22bcc656655ea11c Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Thu, 4 Aug 2016 14:37:20 +0300 Subject: [PATCH 615/838] MAGETWO-49542: Managing Tier Prices MAGETWO-55965: Integrate new CG component --- .../Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php | 1 + .../Source/GroupSourceForLoggedInCustomersInterface.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 37c4382ea05..2796c5e855a 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -82,6 +82,7 @@ class AdvancedPricing extends AbstractModifier * @var array */ protected $meta = []; + /** * @var GroupSourceInterface */ diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php index e71ecfdd50a..be44b12314b 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php @@ -11,4 +11,4 @@ use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; interface GroupSourceForLoggedInCustomersInterface extends OptionArrayInterface { -} \ No newline at end of file +} -- GitLab From 0501b1564ca5b8b513d12e9dd6308fc424aceb04 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Thu, 4 Aug 2016 15:05:03 +0300 Subject: [PATCH 616/838] MAGETWO-49542: Managing Tier Prices MAGETWO-55965: Integrate new CG component - Fix tests --- .../Product/Form/Modifier/AdvancedPricing.php | 10 +++++----- .../Model/Customer/Source/GroupSourceInterface.php | 2 +- .../Source/GroupSourceWithAllGroupsInterface.php | 3 +-- .../Model/Customer/Source/GroupWithoutAllSources.php | 7 +++++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 2796c5e855a..4e4f6e19694 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -7,7 +7,7 @@ namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Model\Locator\LocatorInterface; -use Magento\Customer\Model\Customer\Source\GroupSourceInterface; +use Magento\Customer\Model\Customer\Source\GroupSourceWithAllGroupsInterface; use Magento\Directory\Helper\Data; use Magento\Framework\App\ObjectManager; use Magento\Store\Model\StoreManagerInterface; @@ -84,7 +84,7 @@ class AdvancedPricing extends AbstractModifier protected $meta = []; /** - * @var GroupSourceInterface + * @var GroupSourceWithAllGroupsInterface */ private $customerGroupSource; @@ -98,7 +98,7 @@ class AdvancedPricing extends AbstractModifier * @param Data $directoryHelper * @param ArrayManager $arrayManager * @param string $scopeName - * @param GroupSourceInterface $customerGroupSource + * @param GroupSourceWithAllGroupsInterface $customerGroupSource * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -111,7 +111,7 @@ class AdvancedPricing extends AbstractModifier Data $directoryHelper, ArrayManager $arrayManager, $scopeName = '', - GroupSourceInterface $customerGroupSource = null + GroupSourceWithAllGroupsInterface $customerGroupSource = null ) { $this->locator = $locator; $this->storeManager = $storeManager; @@ -123,7 +123,7 @@ class AdvancedPricing extends AbstractModifier $this->arrayManager = $arrayManager; $this->scopeName = $scopeName; $this->customerGroupSource = $customerGroupSource - ?: ObjectManager::getInstance()->get(GroupSourceInterface::class); + ?: ObjectManager::getInstance()->get(GroupSourceWithAllGroupsInterface::class); } /** diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php index 4e1fcf4a639..9d0cfe08af8 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php @@ -11,4 +11,4 @@ use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; interface GroupSourceInterface extends OptionArrayInterface { -} \ No newline at end of file +} diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php index ef60c4cc995..75150ef813e 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php @@ -7,7 +7,6 @@ namespace Magento\Customer\Model\Customer\Source; use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; - interface GroupSourceWithAllGroupsInterface extends OptionArrayInterface { -} \ No newline at end of file +} diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php index e90e57bdd6a..52480f51474 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php @@ -8,7 +8,10 @@ namespace Magento\Customer\Model\Customer\Source; use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; -class GroupWithoutAllSources extends Group implements OptionArrayInterface +class GroupWithoutAllSources extends Group implements GroupSourceInterface { + /** + * @var bool + */ protected $isShowAllGroupsValue = false; -} \ No newline at end of file +} -- GitLab From 7e38a19429e48a41f9ef522f60cc7bdf56859440 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 11:11:04 +0300 Subject: [PATCH 617/838] MAGETWO-49542: Managing Tier Prices - MAGETWO-55965: Integrate new CG component - Fix unit tests --- .../Unit/Model/Config/Source/GroupTest.php | 39 ++++++++++++++----- .../Unit/Model/Customer/Source/GroupTest.php | 6 +-- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php index edb3405451e..e097f487cbb 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php @@ -6,10 +6,19 @@ */ namespace Magento\Customer\Test\Unit\Model\Config\Source; +use Magento\Customer\Model\Config\Source\Group; +use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + class GroupTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Customer\Model\Config\Source\Group + * @var GroupSourceForLoggedInCustomersInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $groupSource; + + /** + * @var Group */ protected $model; @@ -25,20 +34,30 @@ class GroupTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->groupServiceMock = $this->getMock(\Magento\Customer\Api\GroupManagementInterface::class); - $this->converterMock = $this->getMock(\Magento\Framework\Convert\DataObject::class, [], [], '', false); - $this->model = - new \Magento\Customer\Model\Config\Source\Group($this->groupServiceMock, $this->converterMock); + $this->groupServiceMock = $this->getMock(GroupManagementInterface::class); + $this->converterMock = $this->getMock(DataObject::class, [], [], '', false); + $this->groupSource = $this->getMockBuilder(GroupSourceForLoggedInCustomersInterface::class) + ->getMockForAbstractClass(); + $this->model = (new ObjectManager($this))->getObject( + Group::class, + [ + 'groupManagement' => $this->groupServiceMock, + 'converter' => $this->converterMock, + 'groupSourceForLoggedInCustomers' => $this->groupSource, + ] + ); } public function testToOptionArray() { $expectedValue = ['General', 'Retail']; - $this->groupServiceMock->expects($this->once()) - ->method('getLoggedInGroups') - ->will($this->returnValue($expectedValue)); - $this->converterMock->expects($this->once())->method('toOptionArray') - ->with($expectedValue, 'id', 'code')->will($this->returnValue($expectedValue)); + $this->groupServiceMock->expects($this->never())->method('getLoggedInGroups'); + $this->converterMock->expects($this->never())->method('toOptionArray'); + + $this->groupSource->expects($this->once()) + ->method('toOptionArray') + ->willReturn($expectedValue); + array_unshift($expectedValue, ['value' => '', 'label' => __('-- Please Select --')]); $this->assertEquals($expectedValue, $this->model->toOptionArray()); } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php index 1228d97ac57..d9ca3bdc1ba 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php @@ -5,7 +5,7 @@ */ namespace Magento\Customer\Test\Unit\Model\Customer\Source; -use Magento\Customer\Model\Customer\Source\GroupSource; +use Magento\Customer\Model\Customer\Source\Group; use Magento\Framework\Module\Manager; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -15,7 +15,7 @@ use Magento\Customer\Api\Data\GroupSearchResultsInterface; class GroupTest extends \PHPUnit_Framework_TestCase { /** - * @var GroupSource + * @var Group */ private $model; @@ -61,7 +61,7 @@ class GroupTest extends \PHPUnit_Framework_TestCase $this->searchResultMock = $this->getMockBuilder(GroupSearchResultsInterface::class) ->getMockForAbstractClass(); - $this->model = new GroupSource( + $this->model = new Group( $this->moduleManagerMock, $this->groupRepositoryMock, $this->searchCriteriaBuilderMock -- GitLab From dab1880ddc99c56241b418d585900f7548048050 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Thu, 18 Aug 2016 19:54:34 +0300 Subject: [PATCH 618/838] MAGETWO-49542: Managing Tier Prices MAGETWO-55965: Integrate new CG component - Fix static tests --- .../Customer/Test/Unit/Model/Config/Source/GroupTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php index e097f487cbb..d7693a25653 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php @@ -6,8 +6,10 @@ */ namespace Magento\Customer\Test\Unit\Model\Config\Source; +use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Model\Config\Source\Group; use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; +use Magento\Framework\Convert\DataObject; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class GroupTest extends \PHPUnit_Framework_TestCase -- GitLab From c5cfaa85a4df484aad48508bb39cd2e08decc410 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Mon, 8 Aug 2016 10:28:40 +0300 Subject: [PATCH 619/838] MAGETWO-49542: Managing Tier Prices MAGETWO-55965: Integrate new CG component - Fixes after code review --- .../Product/Form/Modifier/AdvancedPricing.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 4e4f6e19694..3905905e7e7 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -199,24 +199,6 @@ class AdvancedPricing extends AbstractModifier } return $this->customerGroupSource->toOptionArray(); - - $customerGroups = [ - [ - 'label' => __('ALL GROUPS'), - 'value' => GroupInterface::CUST_GROUP_ALL, - ] - ]; - - /** @var GroupInterface[] $groups */ - $groups = $this->groupRepository->getList($this->searchCriteriaBuilder->create()); - foreach ($groups->getItems() as $group) { - $customerGroups[] = [ - 'label' => $group->getCode(), - 'value' => $group->getId(), - ]; - } - - return $customerGroups; } /** -- GitLab From 26a16ae2521641fa65ac7a6fbe8439652b480f1e Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Thu, 11 Aug 2016 10:21:06 +0300 Subject: [PATCH 620/838] MAGETWO-49542: Managing Tier Prices MAGETWO-55965: Integrate new CG component - Fix tests --- .../Config/Source/Group/MultiselectTest.php | 30 ---------------- .../Model/Config/Source/GroupTest.php | 35 ++++++++++++++----- 2 files changed, 27 insertions(+), 38 deletions(-) delete mode 100644 dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php deleted file mode 100644 index d337d9a7642..00000000000 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Customer\Model\Config\Source\Group; - -use Magento\TestFramework\Helper\Bootstrap; - -/** - * Class \Magento\Customer\Model\Config\Source\Group\Multiselect - */ -class MultiselectTest extends \PHPUnit_Framework_TestCase -{ - public function testToOptionArray() - { - /** @var Multiselect $multiselect */ - $multiselect = Bootstrap::getObjectManager()->get( - \Magento\Customer\Model\Config\Source\Group\Multiselect::class - ); - $this->assertEquals( - [ - ['value' => 1, 'label' => 'General'], - ['value' => 2, 'label' => 'Wholesale'], - ['value' => 3, 'label' => 'Retailer'], - ], - $multiselect->toOptionArray() - ); - } -} diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/GroupTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/GroupTest.php index b4674c7b6aa..3d0776d058f 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/GroupTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/GroupTest.php @@ -16,14 +16,33 @@ class GroupTest extends \PHPUnit_Framework_TestCase { /** @var Group $group */ $group = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Config\Source\Group::class); - $this->assertEquals( - [ - ['value' => '', 'label' => '-- Please Select --'], - ['value' => 1, 'label' => 'General'], - ['value' => 2, 'label' => 'Wholesale'], - ['value' => 3, 'label' => 'Retailer'], - ], - $group->toOptionArray() + $options = $group->toOptionArray(); + $this->assertContainsOptionRecursive('', '-- Please Select --', $options); + } + + private function assertContainsOptionRecursive($expectedValue, $expectedLabel, array $values) + { + $this->assertTrue( + $this->hasOptionLabelRecursive($expectedValue, $expectedLabel, $values), + 'Label ' . $expectedLabel . ' not found' ); } + + private function hasOptionLabelRecursive($value, $label, array $values) + { + $hasLabel = false; + foreach ($values as $option) { + $this->assertArrayHasKey('label', $option); + $this->assertArrayHasKey('value', $option); + if (strpos((string)$option['label'], (string)$label) !== false) { + $this->assertEquals($value, $option['value']); + $hasLabel = true; + break; + } elseif (is_array($option['value'])) { + $hasLabel |= $this->hasOptionLabelRecursive($value, $label, $option['value']); + } + } + + return (bool)$hasLabel; + } } -- GitLab From 91f8a2384cb8d5280dfd58f823a1e3c0b29f97f2 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Thu, 18 Aug 2016 16:28:51 +0300 Subject: [PATCH 621/838] MAGETWO-55908: Prepare PR --- .../adminhtml/web/js/form/element/price-input.js | 10 +--------- .../Unit/Model/Product/Type/ConfigurableTest.php | 4 ++-- .../Model/Import/Entity/EavAbstractTest.php | 12 +++++++++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js index 91132efa56a..0939619809a 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js @@ -10,14 +10,6 @@ define([ return Abstract.extend({ defaults: { elementTmpl: 'Magento_Catalog/form/element/price-input' - }, - - /** - * Callback that fires when 'input' event is performed - * - * @param {Object} data - * @param {Object} event - */ - onInput: function (data, event) {} + } }); }); 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 21730cf65f0..efb409dd156 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 @@ -384,7 +384,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase 'addAttributeToSelect', 'addFilterByRequiredOptions', 'setStoreId', - 'addPriceData', + 'addTierPriceData', 'getIterator', 'load', ] @@ -393,7 +393,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $productCollection->expects($this->any())->method('addAttributeToSelect')->will($this->returnSelf()); $productCollection->expects($this->any())->method('setProductFilter')->will($this->returnSelf()); $productCollection->expects($this->any())->method('setFlag')->will($this->returnSelf()); - $productCollection->expects($this->any())->method('addPriceData')->will($this->returnSelf()); + $productCollection->expects($this->any())->method('addTierPriceData')->will($this->returnSelf()); $productCollection->expects($this->any())->method('addFilterByRequiredOptions')->will($this->returnSelf()); $productCollection->expects($this->any())->method('setStoreId')->with(5)->will($this->returnValue([])); $productCollection->expects($this->any())->method('getIterator')->willReturn( diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/EavAbstractTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/EavAbstractTest.php index c1e9be87a9a..e3810fc0766 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/EavAbstractTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/EavAbstractTest.php @@ -52,11 +52,17 @@ class EavAbstractTest extends \PHPUnit_Framework_TestCase $index = $attribute->getAttributeCode() == $indexAttributeCode ? 'value' : 'label'; $expectedOptions = []; foreach ($attribute->getSource()->getAllOptions(false) as $option) { - $expectedOptions[strtolower($option[$index])] = $option['value']; + if (is_array($option['value'])) { + foreach ($option['value'] as $value) { + $expectedOptions[strtolower($value[$index])] = $value['value']; + } + } else { + $expectedOptions[strtolower($option[$index])] = $option['value']; + } } $actualOptions = $this->_model->getAttributeOptions($attribute, [$indexAttributeCode]); - sort($expectedOptions); - sort($actualOptions); + asort($expectedOptions); + asort($actualOptions); $this->assertEquals($expectedOptions, $actualOptions); } } -- GitLab From 41ba638533a4e03d6a03d35e8110e3892139c4bc Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 11:43:21 +0300 Subject: [PATCH 622/838] MAGETWO-55908: Prepare PR --- ...pedProductTierPriceManagementInterface.php | 3 - .../Product/ScopedTierPriceManagement.php | 180 +++++++----------- .../Source/GroupWithoutAllSources.php | 2 - 3 files changed, 72 insertions(+), 113 deletions(-) diff --git a/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php b/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php index 8a27480b776..b3a9beacea3 100644 --- a/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php +++ b/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php @@ -6,9 +6,6 @@ */ namespace Magento\Catalog\Api; -/** - * @api - */ interface ScopedProductTierPriceManagementInterface { /** diff --git a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php index 34f90331ddd..f08702bdd73 100644 --- a/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php +++ b/app/code/Magento/Catalog/Model/Product/ScopedTierPriceManagement.php @@ -1,138 +1,132 @@ <?php /** - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Catalog\Model\Product; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Customer\Api\GroupManagementInterface; -use Magento\Framework\Exception\CouldNotSaveException; -use Magento\Framework\Exception\InputException; +use Magento\Catalog\Api\Data\ProductTierPriceInterface; +use Magento\Catalog\Api\ScopedProductTierPriceManagementInterface; +use Magento\Store\Model\ScopeInterface; -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTierPriceManagementInterface +class ScopedTierPriceManagement implements ScopedProductTierPriceManagementInterface { /** * @var \Magento\Catalog\Api\ProductRepositoryInterface */ - protected $productRepository; - - /** - * @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory - */ - protected $priceFactory; + private $productRepository; /** * @var \Magento\Store\Model\StoreManagerInterface */ - protected $storeManager; + private $storeManager; /** - * @var \Magento\Catalog\Model\Product\PriceModifier + * @var \Magento\Framework\App\Config\ScopeConfigInterface */ - protected $priceModifier; + private $config; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface + * @var PriceModifier */ - protected $config; + private $priceModifier; /** - * @var GroupManagementInterface + * @var TierPriceManagement */ - protected $groupManagement; + private $tierPriceManagement; /** - * @param ProductRepositoryInterface $productRepository - * @param \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $priceFactory + * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param PriceModifier $priceModifier * @param \Magento\Framework\App\Config\ScopeConfigInterface $config - * @param GroupManagementInterface $groupManagement + * @param PriceModifier $priceModifier + * @param TierPriceManagement $tierPriceManagement */ public function __construct( - ProductRepositoryInterface $productRepository, - \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $priceFactory, + \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Catalog\Model\Product\PriceModifier $priceModifier, \Magento\Framework\App\Config\ScopeConfigInterface $config, - GroupManagementInterface $groupManagement + PriceModifier $priceModifier, + TierPriceManagement $tierPriceManagement ) { $this->productRepository = $productRepository; - $this->priceFactory = $priceFactory; $this->storeManager = $storeManager; $this->priceModifier = $priceModifier; $this->config = $config; - $this->groupManagement = $groupManagement; + $this->tierPriceManagement = $tierPriceManagement; } /** * {@inheritdoc} - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function add($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) + public function add($sku, ProductTierPriceInterface $tierPrice) { - $this->validatePrice($tierPrice); $product = $this->productRepository->get($sku, ['edit_mode' => true]); - $tierPrices = $product->getTierPrices(); - $websiteIdentifier = 0; - $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); - if ($value != 0) { - $websiteIdentifier = $this->storeManager->getWebsite()->getId(); + $product->setTierPrices( + $this->prepareTierPrices($product->getTierPrices(), $tierPrice) + ); + try { + $this->productRepository->save($product); + } catch (\Exception $e) { + throw new \Magento\Framework\Exception\CouldNotSaveException(__('Could not save group price')); } - $found = false; + return true; + } + + /** + * @param array $tierPrices + * @param ProductTierPriceInterface $tierPrice + * @return ProductTierPriceInterface[]|null + */ + private function prepareTierPrices(array $tierPrices, ProductTierPriceInterface $tierPrice) + { + $this->validate($tierPrice); + $websiteId = $this->getWebsiteId(); + + foreach ($tierPrices as $index => $item) { + $tierPriceWebsite = $tierPrice->getExtensionAttributes() + ? $tierPrice->getExtensionAttributes()->getWebsiteId() + : 0; - foreach ($tierPrices as $item) { - $tierPriceWebsite = - $tierPrice->getExtensionAttributes() ? $tierPrice->getExtensionAttributes()->getWebsiteId() : 0; if ($item->getCustomerGroupId() == $tierPrice->getCustomerGroupId() - && $websiteIdentifier == $tierPriceWebsite - && $item->getQty() == $tierPrice->getQty()) { - $item->setValue($tierPrice->getValue()); - $item->getExtensionAttributes() - ->setPercentageValue($tierPrice->getExtensionAttributes()->getPercentageValue()); - $found = true; + && $websiteId == $tierPriceWebsite + && $item->getQty() == $tierPrice->getQty() + ) { + unset($tierPrices[$index]); break; } } - if (!$found) { - $tierPrices[] = $tierPrice; - } - $product->setTierPrices($tierPrices); - $errors = $product->validate(); - if (is_array($errors) && count($errors)) { - $errorAttributeCodes = implode(', ', array_keys($errors)); - throw new InputException( - __('Values of following attributes are invalid: %1', $errorAttributeCodes) - ); - } - try { - $this->productRepository->save($product); - } catch (\Exception $e) { - throw new CouldNotSaveException(__('Could not save group price')); + $tierPrices[] = $tierPrice; + return $tierPrices; + } + + /** + * @return int + */ + private function getWebsiteId() + { + $websiteIdentifier = 0; + $value = $this->config->getValue('catalog/price/scope', ScopeInterface::SCOPE_WEBSITE); + if ($value != 0) { + $websiteIdentifier = $this->storeManager->getWebsite()->getId(); } - return true; + + return $websiteIdentifier; } /** - * @param \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice + * @param ProductTierPriceInterface $tierPrice + * @throws \Magento\Framework\Exception\InputException * @return void - * @throws InputException - * @throws \Zend_Validate_Exception */ - protected function validatePrice(\Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) + private function validate(ProductTierPriceInterface $tierPrice) { - $data = ['qty' => $tierPrice->getQty()]; + $data = ['qty' => $tierPrice->getQty(), 'price' => $tierPrice->getValue()]; foreach ($data as $value) { - if (!\Zend_Validate::is($value, 'Float') || $value <= 0) { - throw new InputException(__('Please provide valid data')); + if (!is_float($value) || $value <= 0) { + throw new \Magento\Framework\Exception\InputException(__('Please provide valid data')); } } } @@ -140,19 +134,14 @@ class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTie /** * {@inheritdoc} */ - public function remove($sku, \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice) + public function remove($sku, ProductTierPriceInterface $tierPrice) { $product = $this->productRepository->get($sku, ['edit_mode' => true]); - $websiteIdentifier = 0; - $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); - if ($value != 0) { - $websiteIdentifier = $this->storeManager->getWebsite()->getId(); - } $this->priceModifier->removeTierPrice( $product, $tierPrice->getCustomerGroupId(), $tierPrice->getQty(), - $websiteIdentifier + $this->getWebsiteId() ); return true; } @@ -162,31 +151,6 @@ class ScopedTierPriceManagement implements \Magento\Catalog\Api\ScopedProductTie */ public function getList($sku, $customerGroupId) { - $product = $this->productRepository->get($sku, ['edit_mode' => true]); - - $priceKey = 'website_price'; - $value = $this->config->getValue('catalog/price/scope', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITE); - if ($value == 0) { - $priceKey = 'price'; - } - - $cgi = ($customerGroupId === 'all' - ? $this->groupManagement->getAllCustomersGroup()->getId() - : $customerGroupId); - - $prices = []; - foreach ($product->getData('tier_price') as $price) { - if ((is_numeric($customerGroupId) && intval($price['cust_group']) === intval($customerGroupId)) - || ($customerGroupId === 'all' && $price['all_groups']) - ) { - /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterface $tierPrice */ - $tierPrice = $this->priceFactory->create(); - $tierPrice->setValue($price[$priceKey]) - ->setQty($price['price_qty']) - ->setCustomerGroupId($cgi); - $prices[] = $tierPrice; - } - } - return $prices; + return $this->tierPriceManagement->getList($sku, $customerGroupId); } } diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php index 52480f51474..44455b418c0 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php @@ -6,8 +6,6 @@ namespace Magento\Customer\Model\Customer\Source; -use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; - class GroupWithoutAllSources extends Group implements GroupSourceInterface { /** -- GitLab From 14e6b5dc6792d296be98b9fe66da3f4b0a6c99ee Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 22 Aug 2016 13:10:30 +0300 Subject: [PATCH 623/838] MAGETWO-55908: Prepare PR --- .../Catalog/Api/ScopedProductTierPriceManagementInterface.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php b/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php index b3a9beacea3..8a27480b776 100644 --- a/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php +++ b/app/code/Magento/Catalog/Api/ScopedProductTierPriceManagementInterface.php @@ -6,6 +6,9 @@ */ namespace Magento\Catalog\Api; +/** + * @api + */ interface ScopedProductTierPriceManagementInterface { /** -- GitLab From 266a261fd540cad2caf656e245d6b2c645a3b5e8 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 11:43:25 +0300 Subject: [PATCH 624/838] MAGETWO-55908: Prepare PR --- .../Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index acb76ab1f3c..b386c9d3036 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -64,7 +64,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->objectManagerHelper = new ObjectManagerHelper($this); $this->product = $this->objectManagerHelper->getObject(\Magento\Catalog\Model\Product::class); - $this->tpFactory = $this->getMockForAbstractClass( + $this->tpFactory = $this->getMock( \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class, ['create'], '', -- GitLab From 66decd0175530c6fb976bbe138662183cd4aa726 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 23 Aug 2016 12:23:47 +0300 Subject: [PATCH 625/838] MAGETWO-55908: Prepare PR --- .../Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php index b386c9d3036..5868e749446 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Type/PriceTest.php @@ -67,6 +67,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase $this->tpFactory = $this->getMock( \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory::class, ['create'], + [], '', false, false, -- GitLab From 8857b216fdf7a58ee3a84ed785e0d6a19a664fba Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Tue, 23 Aug 2016 12:26:23 +0300 Subject: [PATCH 626/838] MAGETWO-57227: Payments configuration sections default setting are wrong - symbol arrows replaced with css arrows --- app/code/Magento/Paypal/view/adminhtml/web/styles.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Paypal/view/adminhtml/web/styles.css b/app/code/Magento/Paypal/view/adminhtml/web/styles.css index 456a6aff73c..99ab1fc4850 100644 --- a/app/code/Magento/Paypal/view/adminhtml/web/styles.css +++ b/app/code/Magento/Paypal/view/adminhtml/web/styles.css @@ -27,9 +27,9 @@ .paypal-top-section.active > .entry-edit-head.admin__collapsible-block {border-bottom: 1px solid #ccc;} .paypal-top-section > .admin__collapsible-block > a {font-size: 1.4rem; font-weight: normal; text-transform: uppercase;} .paypal-recommended-header > .admin__collapsible-block > a::before {content: "" !important;} -.paypal-other-header > .admin__collapsible-block > a.open::before {content: "\25B2" !important;} -.paypal-other-header > .admin__collapsible-block > a::before {color: #000; content: "\25BC" !important; font-size: 1rem; top: 2.2rem;} +.paypal-other-header > .admin__collapsible-block > a::before {content: '' !important; width: 0; height: 0; border-color: transparent; border-top-color: #000; border-style: solid; border-width: 0.8rem .5rem 0 .5rem; margin-top:1px; transition: all .2s linear;} +.paypal-other-header > .admin__collapsible-block > a.open::before {border-color: transparent; border-bottom-color: #000; border-width: 0 .5rem 0.8rem .5rem;} .paypal-other-header > .admin__collapsible-block > a {color: #007bdb !important; text-align: right;} .payments-other-header > .admin__collapsible-block > a {display: inline-block;} -.payments-other-header > .admin__collapsible-block > a::before {content: "\25BC" !important; font-size: 1rem;} -.payments-other-header > .admin__collapsible-block > a.open::before {content: "\25B2" !important;} \ No newline at end of file +.payments-other-header > .admin__collapsible-block > a::before {content: '' !important; width: 0; height: 0; border-color: transparent; border-top-color: #000; border-style: solid; border-width: 0.8rem .5rem 0 .5rem; margin-top:1px; transition: all .2s linear;} +.payments-other-header > .admin__collapsible-block > a.open::before {border-color: transparent; border-bottom-color: #000; border-width: 0 .5rem 0.8rem .5rem;} \ No newline at end of file -- GitLab From 751bf4ceb68e7e99166a3079a2443ce204516df8 Mon Sep 17 00:00:00 2001 From: Iurii Ivashchenko <iivashchenko@magento.com> Date: Tue, 23 Aug 2016 12:43:41 +0300 Subject: [PATCH 627/838] MAGETWO-57227: Payments configuration sections default setting are wrong - code style fixes --- app/code/Magento/Paypal/view/adminhtml/web/styles.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Paypal/view/adminhtml/web/styles.css b/app/code/Magento/Paypal/view/adminhtml/web/styles.css index 99ab1fc4850..9e7cfb2afc1 100644 --- a/app/code/Magento/Paypal/view/adminhtml/web/styles.css +++ b/app/code/Magento/Paypal/view/adminhtml/web/styles.css @@ -16,7 +16,7 @@ .payflow-settings-notice ul.options-list {list-style:disc;padding:0 2em;} .paypal-express-section .heading {display: inline-block; background: url("images/pp-logo-200px.png") no-repeat 0 50% / 18rem auto; padding-left: 20rem;} .paypal-express-section .button-container {display: inline-block; float: right;} -.paypal-express-section .config-alt {background: url("images/pp-alt.png") no-repeat; height: 26px; margin: 0.5rem 0 0; width: 158px;} +.paypal-express-section .config-alt {background: url("images/pp-alt.png") no-repeat; height: 26px; margin: .5rem 0 0; width: 158px;} .paypal-express-section .link-more {margin-left: 5px;} .paypal-other-section .heading {display: inline-block;} .paypal-other-section .button-container {display: inline-block; float: right; margin: 1rem 0 0 !important;} @@ -27,9 +27,9 @@ .paypal-top-section.active > .entry-edit-head.admin__collapsible-block {border-bottom: 1px solid #ccc;} .paypal-top-section > .admin__collapsible-block > a {font-size: 1.4rem; font-weight: normal; text-transform: uppercase;} .paypal-recommended-header > .admin__collapsible-block > a::before {content: "" !important;} -.paypal-other-header > .admin__collapsible-block > a::before {content: '' !important; width: 0; height: 0; border-color: transparent; border-top-color: #000; border-style: solid; border-width: 0.8rem .5rem 0 .5rem; margin-top:1px; transition: all .2s linear;} -.paypal-other-header > .admin__collapsible-block > a.open::before {border-color: transparent; border-bottom-color: #000; border-width: 0 .5rem 0.8rem .5rem;} +.paypal-other-header > .admin__collapsible-block > a::before {content: '' !important; width: 0; height: 0; border-color: transparent; border-top-color: #000; border-style: solid; border-width: .8rem .5rem 0 .5rem; margin-top:1px; transition: all .2s linear;} +.paypal-other-header > .admin__collapsible-block > a.open::before {border-color: transparent; border-bottom-color: #000; border-width: 0 .5rem .8rem .5rem;} .paypal-other-header > .admin__collapsible-block > a {color: #007bdb !important; text-align: right;} .payments-other-header > .admin__collapsible-block > a {display: inline-block;} -.payments-other-header > .admin__collapsible-block > a::before {content: '' !important; width: 0; height: 0; border-color: transparent; border-top-color: #000; border-style: solid; border-width: 0.8rem .5rem 0 .5rem; margin-top:1px; transition: all .2s linear;} -.payments-other-header > .admin__collapsible-block > a.open::before {border-color: transparent; border-bottom-color: #000; border-width: 0 .5rem 0.8rem .5rem;} \ No newline at end of file +.payments-other-header > .admin__collapsible-block > a::before {content: '' !important; width: 0; height: 0; border-color: transparent; border-top-color: #000; border-style: solid; border-width: .8rem .5rem 0 .5rem; margin-top:1px; transition: all .2s linear;} +.payments-other-header > .admin__collapsible-block > a.open::before {border-color: transparent; border-bottom-color: #000; border-width: 0 .5rem .8rem .5rem;} \ No newline at end of file -- GitLab From 5c76ada4a409f2a9948b3ac3efd9899cff36c1b6 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Tue, 23 Aug 2016 13:11:27 +0300 Subject: [PATCH 628/838] MAGETWO-55345: Grunt uses actual theme's list --- Gruntfile.js.sample | 3 +- dev/tools/grunt/configs/clean.js | 2 +- dev/tools/grunt/configs/combo.js | 2 +- dev/tools/grunt/configs/exec.js | 2 +- dev/tools/grunt/configs/less.js | 2 +- dev/tools/grunt/configs/watch.js | 2 +- dev/tools/grunt/tools/files-router.js | 60 +++++++++++++++++++++++++++ grunt-config.json.sample | 3 ++ 8 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 dev/tools/grunt/tools/files-router.js create mode 100644 grunt-config.json.sample diff --git a/Gruntfile.js.sample b/Gruntfile.js.sample index 44c5e897dd3..ec0cd43ec3c 100644 --- a/Gruntfile.js.sample +++ b/Gruntfile.js.sample @@ -5,12 +5,13 @@ // For performance use one level down: 'name/{,*/}*.js' // If you want to recursively match all subfolders, use: 'name/**/*.js' + module.exports = function (grunt) { 'use strict'; var _ = require('underscore'), path = require('path'), - themes = require('./dev/tools/grunt/configs/themes'), + themes = require('./dev/tools/grunt/tools/files-router').getThemes(), configDir = './dev/tools/grunt/configs', tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'); diff --git a/dev/tools/grunt/configs/clean.js b/dev/tools/grunt/configs/clean.js index 792981a632c..d984620feb6 100644 --- a/dev/tools/grunt/configs/clean.js +++ b/dev/tools/grunt/configs/clean.js @@ -5,7 +5,7 @@ 'use strict'; -var themes = require('./themes'), +var themes = require('../tools/files-router').getThemes(), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/configs/combo.js b/dev/tools/grunt/configs/combo.js index 930b2fd6871..7dca3a268db 100644 --- a/dev/tools/grunt/configs/combo.js +++ b/dev/tools/grunt/configs/combo.js @@ -5,7 +5,7 @@ 'use strict'; -var theme = require('./themes'), +var theme = require('../tools/files-router').getThemes(), path = require('./path'); /** diff --git a/dev/tools/grunt/configs/exec.js b/dev/tools/grunt/configs/exec.js index a26a0d95a54..ee06b371347 100644 --- a/dev/tools/grunt/configs/exec.js +++ b/dev/tools/grunt/configs/exec.js @@ -6,7 +6,7 @@ 'use strict'; var combo = require('./combo'), - themes = require('./themes'), + themes = require('../tools/files-router').getThemes(), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/configs/less.js b/dev/tools/grunt/configs/less.js index 4071b47fa2b..6f3b0f7ae6d 100644 --- a/dev/tools/grunt/configs/less.js +++ b/dev/tools/grunt/configs/less.js @@ -6,7 +6,7 @@ 'use strict'; var combo = require('./combo'), - themes = require('./themes'), + themes = require('../tools/files-router').getThemes(), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/configs/watch.js b/dev/tools/grunt/configs/watch.js index 014b6b065a9..880b7f7e392 100644 --- a/dev/tools/grunt/configs/watch.js +++ b/dev/tools/grunt/configs/watch.js @@ -6,7 +6,7 @@ 'use strict'; var combo = require('./combo'), - themes = require('./themes'), + themes = require('../tools/files-router').getThemes(), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/tools/files-router.js b/dev/tools/grunt/tools/files-router.js new file mode 100644 index 00000000000..dad794004ec --- /dev/null +++ b/dev/tools/grunt/tools/files-router.js @@ -0,0 +1,60 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +'use strict'; + +module.exports = { + defaultConfig: { + 'themes': 'dev/tools/grunt/configs/themes' + }, + + /** + * Immediately invoked function. + * Loads user config file. + */ + userConfig: (function () { + try { + return require(process.cwd() + '/grunt-config'); + } catch (error) { + return null; + } + })(), + + /** + * Loads "themes" file. + * Load priority: + * From user config; + * From default config with ".loc" suffix ; + * From default config; + * + * @returns themes file or error + */ + getThemes: function () { + if (this.userConfig && this.userConfig.themes) { + return require(this.getFullPath(this.userConfig.themes)); + } else { + try { + return require(this.getFullPath(this.defaultConfig.themes + '.loc')); + } catch (error) { + try { + return require(this.getFullPath(this.defaultConfig.themes)); + } catch (error) { + throw error; + } + } + } + }, + + /** + * Generates full path to file. + * + * @param {String} path - relative path to file. + * + * @returns {String} Full path to file + */ + getFullPath: function (path) { + return process.cwd() + '/' + path; + } +}; diff --git a/grunt-config.json.sample b/grunt-config.json.sample new file mode 100644 index 00000000000..7ef28a856f9 --- /dev/null +++ b/grunt-config.json.sample @@ -0,0 +1,3 @@ +{ + "themes": "dev/tools/grunt/configs/local-themes" +} -- GitLab From 030df867d4404a4955e8a24edc92fd644ad9889f Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 23 Aug 2016 07:47:23 -0500 Subject: [PATCH 629/838] MAGETWO-57270: Create unit test to cover change to escapeHtml --- .../Magento/Framework/Test/Unit/EscaperTest.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 7348537c326..044e9c8c0fe 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -62,7 +62,22 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'data' => '<span><b>some text in tags</b></span>', 'expected' => '<span><b>some text in tags</b></span>', 'allowedTags' => ['span', 'b'], - ] + ], + 'string data with allowed tags with attributes 1' => [ + 'data' => 'Only <span id="sku_max_allowed"><b>2</b></span> in stock', + 'expected' => 'Only <span id="sku_max_allowed"><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + 'string data with allowed tags with attributes 2' => [ + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'allowedTags' => ['a'], + ], + 'string data with allowed tags with attributes and not allowed tags' => [ + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<two>three</two></a> or <a href="%2"><span id="action">create an account</span></a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in<two>three</two></a> or <a href="%2"><span id="action">create an account</span></a>', + 'allowedTags' => ['a'], + ], ]; } -- GitLab From c4a1a49be31b18219f400e0453694c3fd08ebacf Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Tue, 23 Aug 2016 15:57:00 +0300 Subject: [PATCH 630/838] MAGETWO-55345: Grunt uses actual theme's list --- Gruntfile.js.sample | 2 +- dev/tools/grunt/configs/clean.js | 2 +- dev/tools/grunt/configs/combo.js | 2 +- dev/tools/grunt/configs/exec.js | 2 +- dev/tools/grunt/configs/less.js | 2 +- dev/tools/grunt/configs/watch.js | 2 +- dev/tools/grunt/tools/files-router.js | 12 ++++++------ 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Gruntfile.js.sample b/Gruntfile.js.sample index ec0cd43ec3c..1e9c191ba11 100644 --- a/Gruntfile.js.sample +++ b/Gruntfile.js.sample @@ -11,7 +11,7 @@ module.exports = function (grunt) { var _ = require('underscore'), path = require('path'), - themes = require('./dev/tools/grunt/tools/files-router').getThemes(), + themes = require('./dev/tools/grunt/tools/files-router').get('themes'), configDir = './dev/tools/grunt/configs', tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'); diff --git a/dev/tools/grunt/configs/clean.js b/dev/tools/grunt/configs/clean.js index d984620feb6..53bcd8a1d83 100644 --- a/dev/tools/grunt/configs/clean.js +++ b/dev/tools/grunt/configs/clean.js @@ -5,7 +5,7 @@ 'use strict'; -var themes = require('../tools/files-router').getThemes(), +var themes = require('../tools/files-router').get('themes'), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/configs/combo.js b/dev/tools/grunt/configs/combo.js index 7dca3a268db..6dcbe7e36a6 100644 --- a/dev/tools/grunt/configs/combo.js +++ b/dev/tools/grunt/configs/combo.js @@ -5,7 +5,7 @@ 'use strict'; -var theme = require('../tools/files-router').getThemes(), +var theme = require('../tools/files-router').get('themes'), path = require('./path'); /** diff --git a/dev/tools/grunt/configs/exec.js b/dev/tools/grunt/configs/exec.js index ee06b371347..3e675ff9b5d 100644 --- a/dev/tools/grunt/configs/exec.js +++ b/dev/tools/grunt/configs/exec.js @@ -6,7 +6,7 @@ 'use strict'; var combo = require('./combo'), - themes = require('../tools/files-router').getThemes(), + themes = require('../tools/files-router').get('themes'), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/configs/less.js b/dev/tools/grunt/configs/less.js index 6f3b0f7ae6d..7a849577127 100644 --- a/dev/tools/grunt/configs/less.js +++ b/dev/tools/grunt/configs/less.js @@ -6,7 +6,7 @@ 'use strict'; var combo = require('./combo'), - themes = require('../tools/files-router').getThemes(), + themes = require('../tools/files-router').get('themes'), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/configs/watch.js b/dev/tools/grunt/configs/watch.js index 880b7f7e392..84657ae7c4d 100644 --- a/dev/tools/grunt/configs/watch.js +++ b/dev/tools/grunt/configs/watch.js @@ -6,7 +6,7 @@ 'use strict'; var combo = require('./combo'), - themes = require('../tools/files-router').getThemes(), + themes = require('../tools/files-router').get('themes'), _ = require('underscore'); var themeOptions = {}; diff --git a/dev/tools/grunt/tools/files-router.js b/dev/tools/grunt/tools/files-router.js index dad794004ec..c120af31df6 100644 --- a/dev/tools/grunt/tools/files-router.js +++ b/dev/tools/grunt/tools/files-router.js @@ -23,7 +23,7 @@ module.exports = { })(), /** - * Loads "themes" file. + * Loads file. * Load priority: * From user config; * From default config with ".loc" suffix ; @@ -31,15 +31,15 @@ module.exports = { * * @returns themes file or error */ - getThemes: function () { - if (this.userConfig && this.userConfig.themes) { - return require(this.getFullPath(this.userConfig.themes)); + get: function (file) { + if (this.userConfig && this.userConfig[file]) { + return require(this.getFullPath(this.userConfig[file])); } else { try { - return require(this.getFullPath(this.defaultConfig.themes + '.loc')); + return require(this.getFullPath(this.defaultConfig[file] + '.loc')); } catch (error) { try { - return require(this.getFullPath(this.defaultConfig.themes)); + return require(this.getFullPath(this.defaultConfig[file])); } catch (error) { throw error; } -- GitLab From 5c4ca762b1b04d38f1115453a1bc24188f7311c8 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Tue, 23 Aug 2016 17:26:44 +0300 Subject: [PATCH 631/838] MAGETWO-53570: PHP Version Check Improvement --- composer.lock | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/composer.lock b/composer.lock index 77553a16419..6fd73ef405c 100644 --- a/composer.lock +++ b/composer.lock @@ -922,16 +922,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "3d265f7c079f5b37d33475f996d7a383c5fc8aeb" + "reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/3d265f7c079f5b37d33475f996d7a383c5fc8aeb", - "reference": "3d265f7c079f5b37d33475f996d7a383c5fc8aeb", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/41f85e9c2582b3f6d1b7d20395fb40c687ad5370", + "reference": "41f85e9c2582b3f6d1b7d20395fb40c687ad5370", "shasum": "" }, "require": { @@ -1010,7 +1010,7 @@ "x.509", "x509" ], - "time": "2016-05-13 01:15:21" + "time": "2016-08-18 18:49:14" }, { "name": "psr/log", @@ -1381,16 +1381,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9" + "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b180b70439dca70049b6b9b7e21d75e6e5d7aca9", - "reference": "b180b70439dca70049b6b9b7e21d75e6e5d7aca9", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8", + "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8", "shasum": "" }, "require": { @@ -1437,20 +1437,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-28 16:56:28" }, { "name": "symfony/filesystem", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7258ddd6f987053f21fa43d03430580ba54e6096" + "reference": "ab4c3f085c8f5a56536845bf985c4cef30bf75fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7258ddd6f987053f21fa43d03430580ba54e6096", - "reference": "7258ddd6f987053f21fa43d03430580ba54e6096", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ab4c3f085c8f5a56536845bf985c4cef30bf75fd", + "reference": "ab4c3f085c8f5a56536845bf985c4cef30bf75fd", "shasum": "" }, "require": { @@ -1486,11 +1486,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:31:50" + "time": "2016-07-20 05:41:28" }, { "name": "symfony/finder", - "version": "v3.1.2", + "version": "v3.1.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -1539,16 +1539,16 @@ }, { "name": "symfony/process", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe" + "reference": "d20332e43e8774ff8870b394f3dd6020cc7f8e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/89f33c16796415ccfd8bb3cf8d520cbb79899bfe", - "reference": "89f33c16796415ccfd8bb3cf8d520cbb79899bfe", + "url": "https://api.github.com/repos/symfony/process/zipball/d20332e43e8774ff8870b394f3dd6020cc7f8e0c", + "reference": "d20332e43e8774ff8870b394f3dd6020cc7f8e0c", "shasum": "" }, "require": { @@ -1584,7 +1584,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-28 11:13:19" }, { "name": "tedivm/jshrink", @@ -3233,35 +3233,35 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.11.5", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "d3d08b76753092a232a4d8c3b94095ac06898719" + "reference": "ddac737e1c06a310a0bb4b3da755a094a31a916a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/d3d08b76753092a232a4d8c3b94095ac06898719", - "reference": "d3d08b76753092a232a4d8c3b94095ac06898719", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/ddac737e1c06a310a0bb4b3da755a094a31a916a", + "reference": "ddac737e1c06a310a0bb4b3da755a094a31a916a", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.3.6", - "sebastian/diff": "~1.1", - "symfony/console": "~2.3|~3.0", - "symfony/event-dispatcher": "~2.1|~3.0", - "symfony/filesystem": "~2.1|~3.0", - "symfony/finder": "~2.1|~3.0", - "symfony/process": "~2.3|~3.0", - "symfony/stopwatch": "~2.5|~3.0" + "php": "^5.3.6 || >=7.0 <7.2", + "sebastian/diff": "^1.1", + "symfony/console": "^2.3 || ^3.0", + "symfony/event-dispatcher": "^2.1 || ^3.0", + "symfony/filesystem": "^2.1 || ^3.0", + "symfony/finder": "^2.1 || ^3.0", + "symfony/process": "^2.3 || ^3.0", + "symfony/stopwatch": "^2.5 || ^3.0" }, "conflict": { "hhvm": "<3.9" }, "require-dev": { "phpunit/phpunit": "^4.5|^5", - "satooshi/php-coveralls": "^0.7.1" + "satooshi/php-coveralls": "^1.0" }, "bin": [ "php-cs-fixer" @@ -3288,7 +3288,7 @@ ], "description": "A tool to automatically fix PHP code style", "abandoned": "friendsofphp/php-cs-fixer", - "time": "2016-07-06 22:49:35" + "time": "2016-08-17 00:17:27" }, { "name": "lusitanian/oauth", @@ -3951,23 +3951,23 @@ }, { "name": "sebastian/environment", - "version": "1.3.7", + "version": "1.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716" + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716", - "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^4.8 || ^5.0" }, "type": "library", "extra": { @@ -3997,7 +3997,7 @@ "environment", "hhvm" ], - "time": "2016-05-17 03:18:57" + "time": "2016-08-18 05:49:44" }, { "name": "sebastian/exporter", @@ -4321,16 +4321,16 @@ }, { "name": "symfony/config", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "0926e69411eba491803dbafb9f1f233e2ced58d0" + "reference": "4275ef5b59f18959df0eee3991e9ca0cc208ffd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/0926e69411eba491803dbafb9f1f233e2ced58d0", - "reference": "0926e69411eba491803dbafb9f1f233e2ced58d0", + "url": "https://api.github.com/repos/symfony/config/zipball/4275ef5b59f18959df0eee3991e9ca0cc208ffd4", + "reference": "4275ef5b59f18959df0eee3991e9ca0cc208ffd4", "shasum": "" }, "require": { @@ -4370,20 +4370,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:31:50" + "time": "2016-07-26 08:02:44" }, { "name": "symfony/dependency-injection", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "2dd85de8216079d1360b2b14988cd5cdbbb49063" + "reference": "f2b5a00d176f6a201dc430375c0ef37706ea3d12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2dd85de8216079d1360b2b14988cd5cdbbb49063", - "reference": "2dd85de8216079d1360b2b14988cd5cdbbb49063", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f2b5a00d176f6a201dc430375c0ef37706ea3d12", + "reference": "f2b5a00d176f6a201dc430375c0ef37706ea3d12", "shasum": "" }, "require": { @@ -4395,7 +4395,7 @@ "require-dev": { "symfony/config": "~2.2|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0", - "symfony/yaml": "~2.1|~3.0.0" + "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" }, "suggest": { "symfony/config": "", @@ -4433,11 +4433,11 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:31:50" + "time": "2016-07-30 07:20:35" }, { "name": "symfony/stopwatch", - "version": "v3.1.2", + "version": "v3.1.3", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", @@ -4486,16 +4486,16 @@ }, { "name": "symfony/yaml", - "version": "v2.8.8", + "version": "v2.8.9", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8" + "reference": "0ceab136f43ed9d3e97b3eea32a7855dc50c121d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/dba4bb5846798cd12f32e2d8f3f35d77045773c8", - "reference": "dba4bb5846798cd12f32e2d8f3f35d77045773c8", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0ceab136f43ed9d3e97b3eea32a7855dc50c121d", + "reference": "0ceab136f43ed9d3e97b3eea32a7855dc50c121d", "shasum": "" }, "require": { @@ -4531,7 +4531,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-06-29 05:29:29" + "time": "2016-07-17 09:06:15" }, { "name": "theseer/fdomdocument", -- GitLab From ef14435e68c9659a74ed22bfe4472857bc9c6ff1 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Tue, 23 Aug 2016 17:35:55 +0300 Subject: [PATCH 632/838] MAGETWO-53569: [Github] Import custom options type 'file' fails #4035 --- .../Model/Import/Product/Option.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php index eaac35ac4f8..d78376e2d14 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Option.php @@ -1137,6 +1137,20 @@ class Option extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity $result[$this->columnMaxCharacters] = $optionRow['max_characters']; } + $result = $this->addFileOptions($result, $optionRow); + + return $result; + } + + /** + * Add file options + * + * @param array $result + * @param array $optionRow + * @return array + */ + private function addFileOptions($result, $optionRow) + { foreach (['file_extension', 'image_size_x', 'image_size_y'] as $fileOptionKey) { if (!isset($optionRow[$fileOptionKey])) { continue; -- GitLab From c6006fff72fc271454fb66949d6f0f0863701190 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 23 Aug 2016 11:13:58 -0500 Subject: [PATCH 633/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../templates/system/config/validatevat.phtml | 2 +- .../templates/tab/view/personal_info.phtml | 20 +++--- .../adminhtml/templates/tab/view/sales.phtml | 14 ++-- .../frontend/templates/account/customer.phtml | 4 +- .../templates/account/dashboard/address.phtml | 12 ++-- .../templates/account/dashboard/info.phtml | 16 ++--- .../account/link/authorization.phtml | 2 +- .../templates/account/link/back.phtml | 2 +- .../templates/account/navigation.phtml | 6 +- .../frontend/templates/address/book.phtml | 30 ++++----- .../frontend/templates/address/edit.phtml | 62 ++++++++--------- .../templates/form/confirmation.phtml | 10 +-- .../view/frontend/templates/form/edit.phtml | 38 +++++------ .../templates/form/forgotpassword.phtml | 10 +-- .../view/frontend/templates/form/login.phtml | 18 ++--- .../frontend/templates/form/newsletter.phtml | 10 +-- .../frontend/templates/form/register.phtml | 66 +++++++++---------- .../form/resetforgottenpassword.phtml | 12 ++-- .../view/frontend/templates/logout.phtml | 2 +- .../view/frontend/templates/newcustomer.phtml | 6 +- .../frontend/templates/widget/gender.phtml | 6 +- .../view/frontend/templates/widget/name.phtml | 6 +- .../frontend/templates/widget/taxvat.phtml | 4 +- 23 files changed, 179 insertions(+), 179 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index be1e66d94b7..77cc24e1b87 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -23,7 +23,7 @@ require(['prototype'], function(){ new Ajax.Request('<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>', { parameters: params, onSuccess: function(response) { - var result = '<?php /* @escapeNotVerified */ echo __('Error during VAT Number verification.') ?>'; + var result = '<?php echo $block->escapeJs($block->escapeHtml(__('Error during VAT Number verification.'))) ?>'; try { if (response.responseText.isJSON()) { response = response.responseText.evalJSON(); diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml index 4b77d2582a7..0d049f1f242 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/personal_info.phtml @@ -16,51 +16,51 @@ $createDateStore = $block->getStoreCreateDate(); ?> <div class="fieldset-wrapper customer-information"> <div class="fieldset-wrapper-title"> - <span class="title"><?php /* @escapeNotVerified */ echo __('Personal Information') ?></span> + <span class="title"><?php echo $block->escapeHtml(__('Personal Information')) ?></span> </div> <table class="admin__table-secondary"> <tbody> <?php echo $block->getChildHtml(); ?> <tr> - <th><?php /* @escapeNotVerified */ echo __('Last Logged In:') ?></th> + <th><?php echo $block->escapeHtml(__('Last Logged In:')) ?></th> <td><?php echo $block->escapeHtml($lastLoginDateAdmin) ?> (<?php echo $block->escapeHtml($block->getCurrentStatus()) ?>)</td> </tr> <?php if ($lastLoginDateAdmin != $lastLoginDateStore): ?> <tr> - <th><?php /* @escapeNotVerified */ echo __('Last Logged In (%1):', $block->getStoreLastLoginDateTimezone()) ?></th> + <th><?php echo $block->escapeHtml(__('Last Logged In (%1):', $block->getStoreLastLoginDateTimezone())) ?></th> <td><?php echo $block->escapeHtml($lastLoginDateStore) ?> (<?php echo $block->escapeHtml($block->getCurrentStatus()) ?>)</td> </tr> <?php endif; ?> <tr> - <th><?php /* @escapeNotVerified */ echo __('Account Lock:') ?></th> + <th><?php echo $block->escapeHtml(__('Account Lock:')) ?></th> <td><?php echo $block->escapeHtml($block->getAccountLock()) ?></td> </tr> <tr> - <th><?php /* @escapeNotVerified */ echo __('Confirmed email:') ?></th> + <th><?php echo $block->escapeHtml(__('Confirmed email:')) ?></th> <td><?php echo $block->escapeHtml($block->getIsConfirmedStatus()) ?></td> </tr> <tr> - <th><?php /* @escapeNotVerified */ echo __('Account Created:') ?></th> + <th><?php echo $block->escapeHtml(__('Account Created:')) ?></th> <td><?php echo $block->escapeHtml($createDateAdmin) ?></td> </tr> <?php if ($createDateAdmin != $createDateStore): ?> <tr> - <th><?php /* @escapeNotVerified */ echo __('Account Created on (%1):', $block->getStoreCreateDateTimezone()) ?></th> + <th><?php echo $block->escapeHtml(__('Account Created on (%1):', $block->getStoreCreateDateTimezone())) ?></th> <td><?php echo $block->escapeHtml($createDateStore) ?></td> </tr> <?php endif; ?> <tr> - <th><?php /* @escapeNotVerified */ echo __('Account Created in:') ?></th> + <th><?php echo $block->escapeHtml(__('Account Created in:')) ?></th> <td><?php echo $block->escapeHtml($block->getCreatedInStore()) ?></td> </tr> <tr> - <th><?php /* @escapeNotVerified */ echo __('Customer Group:') ?></th> + <th><?php echo $block->escapeHtml(__('Customer Group:')) ?></th> <td><?php echo $block->escapeHtml($block->getGroupName()) ?></td> </tr> </tbody> </table> <address> - <strong><?php /* @escapeNotVerified */ echo __('Default Billing Address') ?></strong><br/> + <strong><?php echo $block->escapeHtml(__('Default Billing Address')) ?></strong><br/> <?php echo $block->getBillingAddressHtml() ?> </address> diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml index 4aef50934a5..deb1d1ee40e 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/view/sales.phtml @@ -13,25 +13,25 @@ $singleStoreMode = $block->isSingleStoreMode(); <div class="entry-edit fieldset-wrapper"> <div class="fieldset-wrapper-title"> - <span class="title"><?php /* @escapeNotVerified */ echo __('Sales Statistics') ?></span> + <span class="title"><?php echo $block->escapeHtml(__('Sales Statistics')) ?></span> </div> <table class="data-table"> <thead> <tr> <?php if (!$singleStoreMode): ?> - <th><?php /* @escapeNotVerified */ echo __('Web Site') ?></th> - <th><?php /* @escapeNotVerified */ echo __('Store') ?></th> - <th><?php /* @escapeNotVerified */ echo __('Store View') ?></th> + <th><?php echo $block->escapeHtml(__('Web Site')) ?></th> + <th><?php echo $block->escapeHtml(__('Store')) ?></th> + <th><?php echo $block->escapeHtml(__('Store View')) ?></th> <?php endif; ?> - <th><?php /* @escapeNotVerified */ echo __('Lifetime Sales') ?></th> - <th class="last"><?php /* @escapeNotVerified */ echo __('Average Sale') ?></th> + <th><?php echo $block->escapeHtml(__('Lifetime Sales')) ?></th> + <th class="last"><?php echo $block->escapeHtml(__('Average Sale')) ?></th> </tr> </thead> <?php if (!$singleStoreMode): ?> <tfoot> <tr> - <td colspan="3"><strong><?php /* @escapeNotVerified */ echo __('All Store Views') ?></strong></td> + <td colspan="3"><strong><?php echo $block->escapeHtml(__('All Store Views')) ?></strong></td> <td class="emph"><strong><?php echo $block->escapeHtml($block->formatCurrency($block->getTotals()->getBaseLifetime())) ?></strong></td> <td class="emph last"><strong><?php echo $block->escapeHtml($block->formatCurrency($block->getTotals()->getAvgsale())) ?></strong></td> </tr> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/customer.phtml b/app/code/Magento/Customer/view/frontend/templates/account/customer.phtml index d215028698e..016e4971783 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/customer.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/customer.phtml @@ -5,7 +5,7 @@ */ // @codingStandardsIgnoreFile - +/** @var Magento\Customer\Block\Account\Customer $block */ ?> <?php if($block->customerLoggedIn()): ?> <li class="customer-welcome"> @@ -21,7 +21,7 @@ class="action switch" tabindex="-1" data-action="customer-menu-toggle"> - <span><?php /* @escapeNotVerified */ echo __('Change')?></span> + <span><?php echo $block->escapeHtml(__('Change'))?></span> </button> </span> <script type="text/x-magento-init"> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml index ed6f2a835cf..6c4306e2718 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/address.phtml @@ -10,13 +10,13 @@ ?> <div class="block block-dashboard-addresses"> <div class="block-title"> - <strong><?php /* @escapeNotVerified */ echo __('Address Book') ?></strong> - <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressBookUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Manage Addresses') ?></span></a> + <strong><?php echo $block->escapeHtml(__('Address Book')) ?></strong> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressBookUrl()) ?>"><span><?php echo $block->escapeHtml(__('Manage Addresses')) ?></span></a> </div> <div class="block-content"> <div class="box box-billing-address"> <strong class="box-title"> - <span><?php /* @escapeNotVerified */ echo __('Default Billing Address') ?></span> + <span><?php echo $block->escapeHtml(__('Default Billing Address')) ?></span> </strong> <div class="box-content"> <address> @@ -24,12 +24,12 @@ </address> </div> <div class="box-actions"> - <a class="action edit" href="<?php echo $block->escapeUrl($block->getPrimaryBillingAddressEditUrl()) ?>" data-ui-id="default-billing-edit-link"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getPrimaryBillingAddressEditUrl()) ?>" data-ui-id="default-billing-edit-link"><span><?php echo $block->escapeHtml(__('Edit Address')) ?></span></a> </div> </div> <div class="box box-shipping-address"> <strong class="box-title"> - <span><?php /* @escapeNotVerified */ echo __('Default Shipping Address') ?></span> + <span><?php echo $block->escapeHtml(__('Default Shipping Address')) ?></span> </strong> <div class="box-content"> <address> @@ -37,7 +37,7 @@ </address> </div> <div class="box-actions"> - <a class="action edit" href="<?php echo $block->escapeUrl($block->getPrimaryShippingAddressEditUrl()) ?>" data-ui-id="default-shipping-edit-link"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getPrimaryShippingAddressEditUrl()) ?>" data-ui-id="default-shipping-edit-link"><span><?php echo $block->escapeHtml(__('Edit Address')) ?></span></a> </div> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml index 7eb24b1ffe8..574fe678646 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/dashboard/info.phtml @@ -9,11 +9,11 @@ /** @var \Magento\Customer\Block\Account\Dashboard\Info $block */ ?> <div class="block block-dashboard-info"> - <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Account Information') ?></strong></div> + <div class="block-title"><strong><?php echo $block->escapeHtml(__('Account Information')) ?></strong></div> <div class="block-content"> <div class="box box-information"> <strong class="box-title"> - <span><?php /* @escapeNotVerified */ echo __('Contact Information') ?></span> + <span><?php echo $block->escapeHtml(__('Contact Information')) ?></span> </strong> <div class="box-content"> <p> @@ -23,31 +23,31 @@ </div> <div class="box-actions"> <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('customer/account/edit')) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Edit') ?></span> + <span><?php echo $block->escapeHtml(__('Edit')) ?></span> </a> <a href="<?php echo $block->escapeUrl($block->getChangePasswordUrl()) ?>" class="action change-password"> - <?php /* @escapeNotVerified */ echo __('Change Password') ?> + <?php echo $block->escapeHtml(__('Change Password')) ?> </a> </div> </div> <?php if ($block->isNewsletterEnabled()): ?> <div class="box box-newsletter"> <strong class="box-title"> - <span><?php /* @escapeNotVerified */ echo __('Newsletters') ?></span> + <span><?php echo $block->escapeHtml(__('Newsletters')) ?></span> </strong> <div class="box-content"> <p> <?php if ($block->getIsSubscribed()): ?> - <?php /* @escapeNotVerified */ echo __('You subscribe to "General Subscription".') ?> + <?php echo $block->escapeHtml(__('You subscribe to "General Subscription".')) ?> <?php else: ?> - <?php /* @escapeNotVerified */ echo __('You don\'t subscribe to our newsletter.') ?> + <?php echo $block->escapeHtml(__('You don\'t subscribe to our newsletter.')) ?> <?php endif; ?> </p> <?php /* Extensions placeholder */ ?> <?php echo $block->getChildHtml('customer.account.dashboard.info.extra')?> </div> <div class="box-actions"> - <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('newsletter/manage')) ?>"><span><?php /* @escapeNotVerified */ echo __('Edit') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('newsletter/manage')) ?>"><span><?php echo $block->escapeHtml(__('Edit')) ?></span></a> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml index a6962c20717..7638a8193f4 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml @@ -13,7 +13,7 @@ if ($block->isLoggedIn()) { $dataPostParam = sprintf(" data-post='%s'", $block->getPostParams()); } ?> -<li class="authorization-link" data-label="<?php echo $block->escapeHtml(__('or')); ?>"> +<li class="authorization-link" data-label="<?php echo $block->escapeHtmlAttr(__('or')); ?>"> <a <?php /* @noEscape */ echo $block->getLinkAttributes(); ?><?php /* @noEscape */ echo $dataPostParam; ?>> <?php echo $block->escapeHtml($block->getLabel()); ?> </a> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/back.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/back.phtml index 249d34e529d..2ca281890fe 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/link/back.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/link/back.phtml @@ -8,5 +8,5 @@ ?> <div class="actions-toolbar"> - <div class="secondary"><a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Back') ?></span></a></div> + <div class="secondary"><a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php echo $block->escapeHtml(__('Back')) ?></span></a></div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml b/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml index 65f39d1232c..3c287e2b09d 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/navigation.phtml @@ -3,17 +3,17 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + /** @var $block \Magento\Framework\View\Element\Html\Links */ ?> -<?php /** @var $block \Magento\Customer\Block\Account\Navigation */ ?> <div class="block account-nav"> <div class="title"> - <strong><?php /* @escapeNotVerified */ echo __('My Account'); ?></strong> + <strong><?php echo $block->escapeHtml(__('My Account')); ?></strong> </div> <div class="content"> <nav class="account-nav"> <ul class="nav items"> - <?php echo $block->getChildHtml();?> + <?php echo $block->getChildHtml(); ?> </ul> </nav> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index a642f8b5293..fe45a6132b0 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -9,12 +9,12 @@ /** @var \Magento\Customer\Block\Address\Book $block */ ?> <div class="block block-addresses-default"> - <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Default Addresses') ?></strong></div> + <div class="block-title"><strong><?php echo $block->escapeHtml(__('Default Addresses')) ?></strong></div> <div class="block-content"> <?php if ($_pAddsses = $block->getDefaultBilling()): ?> <div class="box box-address-billing"> <strong class="box-title"> - <span><?php /* @escapeNotVerified */ echo __('Default Billing Address') ?></span> + <span><?php echo $block->escapeHtml(__('Default Billing Address')) ?></span> </strong> <div class="box-content"> <address> @@ -23,15 +23,15 @@ </div> <div class="box-actions"> <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressEditUrl($_pAddsses)) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Change Billing Address') ?></span> + <span><?php echo $block->escapeHtml(__('Change Billing Address')) ?></span> </a> </div> </div> <?php else: ?> <div class="box box-billing-address"> - <strong class="box-title"><span><?php /* @escapeNotVerified */ echo __('Default Billing Address') ?></span></strong> + <strong class="box-title"><span><?php echo $block->escapeHtml(__('Default Billing Address')) ?></span></strong> <div class="box-content"> - <p><?php /* @escapeNotVerified */ echo __('You have no default billing address in your address book.') ?></p> + <p><?php echo $block->escapeHtml(__('You have no default billing address in your address book.')) ?></p> </div> </div> <?php endif ?> @@ -39,7 +39,7 @@ <?php if ($_pAddsses = $block->getDefaultShipping()): ?> <div class="box box-address-shipping"> <strong class="box-title"> - <span><?php /* @escapeNotVerified */ echo __('Default Shipping Address') ?></span> + <span><?php echo $block->escapeHtml(__('Default Shipping Address')) ?></span> </strong> <div class="box-content"> <address> @@ -48,15 +48,15 @@ </div> <div class="box-actions"> <a class="action edit" href="<?php echo $block->escapeUrl($block->getAddressEditUrl($_pAddsses)) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Change Shipping Address') ?></span> + <span><?php echo $block->escapeHtml(__('Change Shipping Address')) ?></span> </a> </div> </div> <?php else: ?> <div class="box box-shipping-address"> - <strong class="box-title"><span><?php /* @escapeNotVerified */ echo __('Default Shipping Address') ?></span></strong> + <strong class="box-title"><span><?php echo $block->escapeHtml(__('Default Shipping Address')) ?></span></strong> <div class="box-content"> - <p><?php /* @escapeNotVerified */ echo __('You have no default shipping address in your address book.') ?></p> + <p><?php echo $block->escapeHtml(__('You have no default shipping address in your address book.')) ?></p> </div> </div> <?php endif ?> @@ -64,7 +64,7 @@ </div> <div class="block block-addresses-list"> - <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Additional Address Entries') ?></strong></div> + <div class="block-title"><strong><?php echo $block->escapeHtml(__('Additional Address Entries')) ?></strong></div> <div class="block-content"> <?php if ($_pAddsses = $block->getAdditionalAddresses()): ?> <ol class="items addresses"> @@ -74,24 +74,24 @@ <?php echo $block->getAddressHtml($_address) ?><br /> </address> <div class="item actions"> - <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('customer/address/edit', ['id' => $_address->getId()])) ?>"><span><?php /* @escapeNotVerified */ echo __('Edit Address') ?></span></a> - <a class="action delete" href="#" role="delete-address" data-address="<?php echo $block->escapeHtmlAttr($_address->getId()) ?>"><span><?php /* @escapeNotVerified */ echo __('Delete Address') ?></span></a> + <a class="action edit" href="<?php echo $block->escapeUrl($block->getUrl('customer/address/edit', ['id' => $_address->getId()])) ?>"><span><?php echo $block->escapeHtml(__('Edit Address')) ?></span></a> + <a class="action delete" href="#" role="delete-address" data-address="<?php echo $block->escapeHtmlAttr($_address->getId()) ?>"><span><?php echo $block->escapeHtml(__('Delete Address')) ?></span></a> </div> </li> <?php endforeach; ?> </ol> <?php else: ?> - <p class="empty"><?php /* @escapeNotVerified */ echo __('You have no other address entries in your address book.') ?></p> + <p class="empty"><?php echo $block->escapeHtml(__('You have no other address entries in your address book.')) ?></p> <?php endif ?> </div> </div> <div class="actions-toolbar"> <div class="primary"> - <button type="button" role="add-address" title="<?php /* @escapeNotVerified */ echo __('Add New Address') ?>" class="action primary add"><span><?php /* @escapeNotVerified */ echo __('Add New Address') ?></span></button> + <button type="button" role="add-address" title="<?php echo $block->escapeHtmlAttr(__('Add New Address')) ?>" class="action primary add"><span><?php echo $block->escapeHtml(__('Add New Address')) ?></span></button> </div> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Back') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php echo $block->escapeHtml(__('Back')) ?></span></a> </div> </div> <script type="text/x-magento-init"> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index f9bdeba5036..15986ca8a6c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -13,61 +13,61 @@ method="post" id="form-validate" enctype="multipart/form-data" - data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> + data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>"> <fieldset class="fieldset"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Contact Information') ?></span></legend><br> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Contact Information')) ?></span></legend><br> <?php echo $block->getBlockHtml('formkey')?> <input type="hidden" name="success_url" value="<?php echo $block->escapeUrl($block->getSuccessUrl()) ?>"> <input type="hidden" name="error_url" value="<?php echo $block->escapeUrl($block->getErrorUrl()) ?>"> <?php echo $block->getNameBlockHtml() ?> <div class="field company"> - <label class="label" for="company"><span><?php /* @escapeNotVerified */ echo __('Company') ?></span></label> + <label class="label" for="company"><span><?php echo $block->escapeHtml(__('Company')) ?></span></label> <div class="control"> <input type="text" name="company" id="company" - title="<?php /* @escapeNotVerified */ echo __('Company') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Company')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getCompany()) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company')) ?>"> </div> </div> <div class="field telephone required"> <label class="label" for="telephone"> - <span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span> + <span><?php echo $block->escapeHtml(__('Phone Number')) ?></span> </label> <div class="control"> <input type="text" name="telephone" value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getTelephone()) ?>" - title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Phone Number')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone')) ?>" id="telephone"> </div> </div> <div class="field fax"> - <label class="label" for="fax"><span><?php /* @escapeNotVerified */ echo __('Fax') ?></span></label> + <label class="label" for="fax"><span><?php echo $block->escapeHtml(__('Fax')) ?></span></label> <div class="control"> <input type="text" name="fax" id="fax" - title="<?php /* @escapeNotVerified */ echo __('Fax') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Fax')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getFax()) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('fax')) ?>"> </div> </div> </fieldset> <fieldset class="fieldset"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Address') ?></span></legend><br> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Address')) ?></span></legend><br> <?php $_streetValidationClass = $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('street'); ?> <div class="field street required"> <label for="street_1" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Street Address') ?></span> + <span><?php echo $block->escapeHtml(__('Street Address')) ?></span> </label> <div class="control"> <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getStreetLine(1)) ?>" - title="<?php /* @escapeNotVerified */ echo __('Street Address') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Street Address')) ?>" id="street_1" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"/> <div class="nested"> @@ -75,12 +75,12 @@ <?php for ($_i = 1, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i < $_n; $_i++): ?> <div class="field additional"> <label class="label" for="street_<?php /* @noEscape */ echo $_i + 1 ?>"> - <span><?php /* @escapeNotVerified */ echo __('Street Address %1', $_i + 1) ?></span> + <span><?php echo $block->escapeHtml(__('Street Address %1', $_i + 1)) ?></span> </label> <div class="control"> <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getStreetLine($_i + 1)) ?>" - title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i + 1) ?>" + title="<?php echo $block->escapeHtmlAttr(__('Street Address %1', $_i + 1)) ?>" id="street_<?php /* @noEscape */ echo $_i + 1 ?>" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> @@ -93,62 +93,62 @@ <?php if ($this->helper('Magento\Customer\Helper\Address')->isVatAttributeVisible()) : ?> <div class="field taxvat"> <label class="label" for="vat_id"> - <span><?php /* @escapeNotVerified */ echo __('VAT Number') ?></span> + <span><?php echo $block->escapeHtml(__('VAT Number')) ?></span> </label> <div class="control"> <input type="text" name="vat_id" value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getVatId()) ?>" - title="<?php /* @escapeNotVerified */ echo __('VAT Number') ?>" + title="<?php echo $block->escapeHtmlAttr(__('VAT Number')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('vat_id')) ?>" id="vat_id"> </div> </div> <?php endif; ?> <div class="field city required"> - <label class="label" for="city"><span><?php /* @escapeNotVerified */ echo __('City') ?></span></label> + <label class="label" for="city"><span><?php echo $block->escapeHtml(__('City')) ?></span></label> <div class="control"> <input type="text" name="city" value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getCity()) ?>" - title="<?php /* @escapeNotVerified */ echo __('City') ?>" + title="<?php echo $block->escapeHtmlAttr(__('City')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city')) ?>" id="city"> </div> </div> <div class="field region required"> <label class="label" for="region_id"> - <span><?php /* @escapeNotVerified */ echo __('State/Province') ?></span> + <span><?php echo $block->escapeHtml(__('State/Province')) ?></span> </label> <div class="control"> <select id="region_id" name="region_id" - title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" + title="<?php echo $block->escapeHtmlAttr(__('State/Province')) ?>" class="validate-select" <?php /* @noEscape */ echo !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : ''; ?>> - <option value=""><?php /* @escapeNotVerified */ echo __('Please select a region, state or province.') ?></option> + <option value=""><?php echo $block->escapeHtml(__('Please select a region, state or province.')) ?></option> </select> <input type="text" id="region" name="region" value="<?php echo $block->escapeHtmlAttr($block->getRegion()) ?>" - title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" + title="<?php echo $block->escapeHtmlAttr(__('State/Province')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>"<?php echo !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : ''; ?>/> </div> </div> <div class="field zip required"> <label class="label" for="zip"> - <span><?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?></span> + <span><?php echo $block->escapeHtml(__('Zip/Postal Code')) ?></span> </label> <div class="control"> <input type="text" name="postcode" value="<?php echo $block->escapeHtmlAttr($block->getAddress()->getPostcode()) ?>" - title="<?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Zip/Postal Code')) ?>" id="zip" class="input-text validate-zip-international <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode')) ?>"> </div> </div> <div class="field country required"> - <label class="label" for="country"><span><?php /* @escapeNotVerified */ echo __('Country') ?></span></label> + <label class="label" for="country"><span><?php echo $block->escapeHtml(__('Country')) ?></span></label> <div class="control"> <?php echo $block->getCountryHtmlSelect() ?> </div> @@ -156,13 +156,13 @@ <?php if ($block->isDefaultBilling()): ?> <div class="message info"> - <span><?php /* @escapeNotVerified */ echo __("It's a default billing address.") ?></span> + <span><?php echo $block->escapeHtml(__("It's a default billing address.")) ?></span> </div> <?php elseif ($block->canSetAsDefaultBilling()): ?> <div class="field choice set billing"> <input type="checkbox" id="primary_billing" name="default_billing" value="1" class="checkbox"> <label class="label" for="primary_billing"> - <span><?php /* @escapeNotVerified */ echo __('Use as my default billing address') ?></span> + <span><?php echo $block->escapeHtml(__('Use as my default billing address')) ?></span> </label> </div> <?php else: ?> @@ -171,13 +171,13 @@ <?php if ($block->isDefaultShipping()): ?> <div class="message info"> - <span><?php /* @escapeNotVerified */ echo __("It's a default shipping address.") ?></span> + <span><?php echo $block->escapeHtml(__("It's a default shipping address.")) ?></span> </div> <?php elseif ($block->canSetAsDefaultShipping()): ?> <div class="field choice set shipping"> <input type="checkbox" id="primary_shipping" name="default_shipping" value="1" class="checkbox"> <label class="label" for="primary_shipping"> - <span><?php /* @escapeNotVerified */ echo __('Use as my default shipping address') ?></span> + <span><?php echo $block->escapeHtml(__('Use as my default shipping address')) ?></span> </label> </div> <?php else: ?> @@ -189,13 +189,13 @@ <button type="submit" class="action save primary" data-action="save-address" - title="<?php /* @escapeNotVerified */ echo __('Save Address') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Save Address') ?></span> + title="<?php echo $block->escapeHtmlAttr(__('Save Address')) ?>"> + <span><?php echo $block->escapeHtml(__('Save Address')) ?></span> </button> </div> <div class="secondary"> <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Go back') ?></span> + <span><?php echo $block->escapeHtml(__('Go back')) ?></span> </a> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml index 2dfcd7f5dd4..b847b798163 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/confirmation.phtml @@ -9,10 +9,10 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> <form action="" method="post" id="form-validate" class="form send confirmation" data-mage-init='{"validation":{}}'> - <fieldset class="fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> - <p class="field note"><?php /* @escapeNotVerified */ echo __('Please enter your email below and we will send you the confirmation link.') ?></p> + <fieldset class="fieldset" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>"> + <p class="field note"><?php echo $block->escapeHtml(__('Please enter your email below and we will send you the confirmation link.')) ?></p> <div class="field email required"> - <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label for="email_address" class="label"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input type="email" name="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtmlAttr($block->getEmail()) ?>" data-validate="{required:true, 'validate-email':true}"> </div> @@ -20,10 +20,10 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" class="action send primary"><span><?php /* @escapeNotVerified */ echo __('Send confirmation link') ?></span></button> + <button type="submit" class="action send primary"><span><?php echo $block->escapeHtml(__('Send confirmation link')) ?></span></button> </div> <div class="secondary"> - <a href="<?php echo $block->escapeUrl($block->getLoginUrl()) ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Sign In') ?></span></a> + <a href="<?php echo $block->escapeUrl($block->getLoginUrl()) ?>" class="action back"><span><?php echo $block->escapeHtml(__('Back to Sign In')) ?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 89219df0e78..0dddf76d722 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -8,10 +8,10 @@ /** @var \Magento\Customer\Block\Form\Edit $block */ ?> -<form class="form form-edit-account" action="<?php echo $block->escapeUrl($block->getUrl('customer/account/editPost')) ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" autocomplete="off"> +<form class="form form-edit-account" action="<?php echo $block->escapeUrl($block->getUrl('customer/account/editPost')) ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>" autocomplete="off"> <fieldset class="fieldset info"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Account Information') ?></span></legend><br> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Account Information')) ?></span></legend><br> <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name')->setObject($block->getCustomer())->toHtml() ?> <?php $_dob = $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Dob') ?> @@ -27,31 +27,31 @@ <?php echo $_gender->setGender($block->getCustomer()->getGender())->toHtml() ?> <?php endif ?> <div class="field choice"> - <input type="checkbox" name="change_email" id="change-email" data-role="change-email" value="1" title="<?php /* @escapeNotVerified */ echo __('Change Email') ?>" class="checkbox" /> - <label class="label" for="change-email"><span><?php /* @escapeNotVerified */ echo __('Change Email') ?></span></label> + <input type="checkbox" name="change_email" id="change-email" data-role="change-email" value="1" title="<?php echo $block->escapeHtmlAttr(__('Change Email')) ?>" class="checkbox" /> + <label class="label" for="change-email"><span><?php echo $block->escapeHtml(__('Change Email')) ?></span></label> </div> <div class="field choice"> - <input type="checkbox" name="change_password" id="change-password" data-role="change-password" value="1" title="<?php /* @escapeNotVerified */ echo __('Change Password') ?>"<?php if ($block->getChangePassword()): ?> checked="checked"<?php endif; ?> class="checkbox" /> - <label class="label" for="change-password"><span><?php /* @escapeNotVerified */ echo __('Change Password') ?></span></label> + <input type="checkbox" name="change_password" id="change-password" data-role="change-password" value="1" title="<?php echo $block->escapeHtmlAttr(__('Change Password')) ?>"<?php if ($block->getChangePassword()): ?> checked="checked"<?php endif; ?> class="checkbox" /> + <label class="label" for="change-password"><span><?php echo $block->escapeHtml(__('Change Password')) ?></span></label> </div> </fieldset> <fieldset class="fieldset password" data-container="change-email-password"> - <legend class="legend"><span data-title="change-email-password"><?php /* @escapeNotVerified */ echo __('Change Email and Password') ?></span></legend><br> + <legend class="legend"><span data-title="change-email-password"><?php echo $block->escapeHtml(__('Change Email and Password')) ?></span></legend><br> <div class="field email required" data-container="change-email"> - <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label class="label" for="email"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> - <input type="email" name="email" id="email" autocomplete="email" data-input="change-email" value="<?php echo $block->escapeHtmlAttr($block->getCustomer()->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" class="input-text" data-validate="{required:true, 'validate-email':true}" /> + <input type="email" name="email" id="email" autocomplete="email" data-input="change-email" value="<?php echo $block->escapeHtmlAttr($block->getCustomer()->getEmail()) ?>" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" class="input-text" data-validate="{required:true, 'validate-email':true}" /> </div> </div> <div class="field password current required"> - <label class="label" for="current-password"><span><?php /* @escapeNotVerified */ echo __('Current Password') ?></span></label> + <label class="label" for="current-password"><span><?php echo $block->escapeHtml(__('Current Password')) ?></span></label> <div class="control"> <input type="password" class="input-text" name="current_password" id="current-password" data-input="current-password" autocomplete="off" /> </div> </div> <div class="field new password required" data-container="new-password" data-mage-init='{"passwordStrengthIndicator": {}}'> - <label class="label" for="password"><span><?php /* @escapeNotVerified */ echo __('New Password') ?></span></label> + <label class="label" for="password"><span><?php echo $block->escapeHtml(__('New Password')) ?></span></label> <div class="control"> <input type="password" class="input-text" name="password" id="password" data-password-min-length="<?php echo $block->escapeHtml($block->getMinimumPasswordLength()) ?>" @@ -61,16 +61,16 @@ autocomplete="off" /> <div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite"> <div id="password-strength-meter" class="password-strength-meter"> - <?php /* @escapeNotVerified */ echo __('Password Strength'); ?>: + <?php echo $block->escapeHtml(__('Password Strength')); ?>: <span id="password-strength-meter-label" data-role="password-strength-meter-label"> - <?php /* @escapeNotVerified */ echo __('No Password'); ?> + <?php echo $block->escapeHtml(__('No Password')); ?> </span> </div> </div> </div> </div> <div class="field confirm password required" data-container="confirm-password"> - <label class="label" for="password-confirmation"><span><?php /* @escapeNotVerified */ echo __('Confirm New Password') ?></span></label> + <label class="label" for="password-confirmation"><span><?php echo $block->escapeHtml(__('Confirm New Password')) ?></span></label> <div class="control"> <input type="password" class="input-text" name="password_confirmation" id="password-confirmation" data-input="confirm-password" @@ -81,10 +81,10 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" class="action save primary" title="<?php /* @escapeNotVerified */ echo __('Save') ?>"><span><?php /* @escapeNotVerified */ echo __('Save') ?></span></button> + <button type="submit" class="action save primary" title="<?php echo $block->escapeHtmlAttr(__('Save')) ?>"><span><?php echo $block->escapeHtml(__('Save')) ?></span></button> </div> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Go back') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php echo $block->escapeHtml(__('Go back')) ?></span></a> </div> </div> </form> @@ -122,9 +122,9 @@ { "[data-role=change-email], [data-role=change-password]": { "changeEmailPassword": { - "titleChangeEmail": "<?php /* @escapeNotVerified */ echo __('Change Email') ?>", - "titleChangePassword": "<?php /* @escapeNotVerified */ echo __('Change Password') ?>", - "titleChangeEmailAndPassword": "<?php /* @escapeNotVerified */ echo __('Change Email and Password') ?>" + "titleChangeEmail": "<?php echo $block->escapeJs(__('Change Email')) ?>", + "titleChangePassword": "<?php echo $block->escapeJs(__('Change Password')) ?>", + "titleChangeEmailAndPassword": "<?php echo $block->escapeJs(__('Change Email and Password')) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml index f7f1ac86007..537208335bd 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/forgotpassword.phtml @@ -15,10 +15,10 @@ method="post" id="form-validate" data-mage-init='{"validation":{}}'> - <fieldset class="fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> - <div class="field note"><?php /* @escapeNotVerified */ echo __('Please enter your email address below to receive a password reset link.'); ?></div> + <fieldset class="fieldset" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>"> + <div class="field note"><?php echo $block->escapeHtml(__('Please enter your email address below to receive a password reset link.')); ?></div> <div class="field email required"> - <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label for="email_address" class="label"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input type="email" name="email" alt="email" id="email_address" class="input-text" value="<?php echo $block->escapeHtmlAttr($block->getEmailValue()) ?>" data-validate="{required:true, 'validate-email':true}"> </div> @@ -27,10 +27,10 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" class="action submit primary"><span><?php /* @escapeNotVerified */ echo __('Reset My Password') ?></span></button> + <button type="submit" class="action submit primary"><span><?php echo $block->escapeHtml(__('Reset My Password')) ?></span></button> </div> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getLoginUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Go back') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getLoginUrl()) ?>"><span><?php echo $block->escapeHtml(__('Go back')) ?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml index 77335cdff76..a4b79d6d0be 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/login.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/login.phtml @@ -10,7 +10,7 @@ ?> <div class="block block-customer-login"> <div class="block-title"> - <strong id="block-customer-login-heading" role="heading" aria-level="2"><?php /* @escapeNotVerified */ echo __('Registered Customers') ?></strong> + <strong id="block-customer-login-heading" role="heading" aria-level="2"><?php echo $block->escapeHtml(__('Registered Customers')) ?></strong> </div> <div class="block-content" aria-labelledby="block-customer-login-heading"> <form class="form form-login" @@ -19,24 +19,24 @@ id="login-form" data-mage-init='{"validation":{}}'> <?php echo $block->getBlockHtml('formkey'); ?> - <fieldset class="fieldset login" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> - <div class="field note"><?php /* @escapeNotVerified */ echo __('If you have an account, sign in with your email address.') ?></div> + <fieldset class="fieldset login" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>"> + <div class="field note"><?php echo $block->escapeHtml(__('If you have an account, sign in with your email address.')) ?></div> <div class="field email required"> - <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label class="label" for="email"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> - <input name="login[username]" value="<?php echo $block->escapeHtmlAttr($block->getUsername()) ?>" <?php if ($block->isAutocompleteDisabled()): ?> autocomplete="off"<?php endif; ?> id="email" type="email" class="input-text" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" data-validate="{required:true, 'validate-email':true}"> + <input name="login[username]" value="<?php echo $block->escapeHtmlAttr($block->getUsername()) ?>" <?php if ($block->isAutocompleteDisabled()): ?> autocomplete="off"<?php endif; ?> id="email" type="email" class="input-text" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" data-validate="{required:true, 'validate-email':true}"> </div> </div> <div class="field password required"> - <label for="pass" class="label"><span><?php /* @escapeNotVerified */ echo __('Password') ?></span></label> + <label for="pass" class="label"><span><?php echo $block->escapeHtml(__('Password')) ?></span></label> <div class="control"> - <input name="login[password]" type="password" <?php if ($block->isAutocompleteDisabled()): ?> autocomplete="off"<?php endif; ?> class="input-text" id="pass" title="<?php /* @escapeNotVerified */ echo __('Password') ?>" data-validate="{required:true}"> + <input name="login[password]" type="password" <?php if ($block->isAutocompleteDisabled()): ?> autocomplete="off"<?php endif; ?> class="input-text" id="pass" title="<?php echo $block->escapeHtmlAttr(__('Password')) ?>" data-validate="{required:true}"> </div> </div> <?php echo $block->getChildHtml('form_additional_info'); ?> <div class="actions-toolbar"> - <div class="primary"><button type="submit" class="action login primary" name="send" id="send2"><span><?php /* @escapeNotVerified */ echo __('Sign In') ?></span></button></div> - <div class="secondary"><a class="action remind" href="<?php echo $block->escapeUrl($block->getForgotPasswordUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Forgot Your Password?') ?></span></a></div> + <div class="primary"><button type="submit" class="action login primary" name="send" id="send2"><span><?php echo $block->escapeHtml(__('Sign In')) ?></span></button></div> + <div class="secondary"><a class="action remind" href="<?php echo $block->escapeUrl($block->getForgotPasswordUrl()) ?>"><span><?php echo $block->escapeHtml(__('Forgot Your Password?')) ?></span></a></div> </div> </fieldset> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml index 51d975fc474..4be5cc17e55 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/newsletter.phtml @@ -12,17 +12,17 @@ <form class="form form-newsletter-manage" action="<?php echo $block->escapeUrl($block->getAction()) ?>" method="post" id="form-validate"> <fieldset class="fieldset"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Subscription option') ?></span></legend><br> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Subscription option')) ?></span></legend><br> <div class="field choice"> - <input type="checkbox" name="is_subscribed" id="subscription" value="1" title="<?php /* @escapeNotVerified */ echo __('General Subscription') ?>"<?php if ($block->getIsSubscribed()): ?> checked="checked"<?php endif; ?> class="checkbox"> - <label for="subscription" class="label"><span><?php /* @escapeNotVerified */ echo __('General Subscription') ?></span></label> + <input type="checkbox" name="is_subscribed" id="subscription" value="1" title="<?php echo $block->escapeHtmlAttr(__('General Subscription')) ?>"<?php if ($block->getIsSubscribed()): ?> checked="checked"<?php endif; ?> class="checkbox"> + <label for="subscription" class="label"><span><?php echo $block->escapeHtml(__('General Subscription')) ?></span></label> </div> <?php /* Extensions placeholder */ ?> <?php echo $block->getChildHtml('customer.form.newsletter.extra')?> </fieldset> <div class="actions-toolbar"> - <div class="primary"><button type="submit" title="<?php /* @escapeNotVerified */ echo __('Save') ?>" class="action save primary"><span><?php /* @escapeNotVerified */ echo __('Save') ?></span></button></div> - <div class="secondary"><a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Back') ?></span></a></div> + <div class="primary"><button type="submit" title="<?php echo $block->escapeHtmlAttr(__('Save')) ?>" class="action save primary"><span><?php echo $block->escapeHtml(__('Save')) ?></span></button></div> + <div class="secondary"><a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php echo $block->escapeHtml(__('Back')) ?></span></a></div> </div> </form> <?php /* Extensions placeholder */ ?> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index b35727b26fb..892179e738a 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -13,14 +13,14 @@ <?php echo $block->getChildHtml('customer.form.register.extra')?> <form class="form create account form-create-account" action="<?php echo $block->escapeUrl($block->getPostActionUrl()) ?>" method="post" id="form-validate" enctype="multipart/form-data" autocomplete="off"> <fieldset class="fieldset create info"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Personal Information') ?></span></legend><br> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Personal Information')) ?></span></legend><br> <input type="hidden" name="success_url" value="<?php echo $block->escapeUrl($block->getSuccessUrl()) ?>"> <input type="hidden" name="error_url" value="<?php echo $block->escapeUrl($block->getErrorUrl()) ?>"> <?php echo $block->getLayout()->createBlock('Magento\Customer\Block\Widget\Name')->setObject($block->getFormData())->setForceUseCustomerAttributes(true)->toHtml() ?> <?php if ($block->isNewsletterEnabled()): ?> <div class="field choice newsletter"> - <input type="checkbox" name="is_subscribed" title="<?php /* @escapeNotVerified */ echo __('Sign Up for Newsletter') ?>" value="1" id="is_subscribed"<?php if ($block->getFormData()->getIsSubscribed()): ?> checked="checked"<?php endif; ?> class="checkbox"> - <label for="is_subscribed" class="label"><span><?php /* @escapeNotVerified */ echo __('Sign Up for Newsletter') ?></span></label> + <input type="checkbox" name="is_subscribed" title="<?php echo $block->escapeHtmlAttr(__('Sign Up for Newsletter')) ?>" value="1" id="is_subscribed"<?php if ($block->getFormData()->getIsSubscribed()): ?> checked="checked"<?php endif; ?> class="checkbox"> + <label for="is_subscribed" class="label"><span><?php echo $block->escapeHtml(__('Sign Up for Newsletter')) ?></span></label> </div> <?php /* Extensions placeholder */ ?> <?php echo $block->getChildHtml('customer.form.register.newsletter')?> @@ -43,36 +43,36 @@ </fieldset> <?php if ($block->getShowAddressFields()): ?> <fieldset class="fieldset address"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Address Information') ?></span></legend><br> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Address Information')) ?></span></legend><br> <input type="hidden" name="create_address" value="1" /> <div class="field company"> - <label for="company" class="label"><span><?php /* @escapeNotVerified */ echo __('Company') ?></span></label> + <label for="company" class="label"><span><?php echo $block->escapeHtml(__('Company')) ?></span></label> <div class="control"> - <input type="text" name="company" id="company" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getCompany()) ?>" title="<?php /* @escapeNotVerified */ echo __('Company') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company')) ?>"> + <input type="text" name="company" id="company" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getCompany()) ?>" title="<?php echo $block->escapeHtmlAttr(__('Company')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('company')) ?>"> </div> </div> <div class="field telephone"> - <label for="telephone" class="label"><span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span></label> + <label for="telephone" class="label"><span><?php echo $block->escapeHtml(__('Phone Number')) ?></span></label> <div class="control"> - <input type="text" name="telephone" id="telephone" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getTelephone()) ?>" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone')) ?>"> + <input type="text" name="telephone" id="telephone" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getTelephone()) ?>" title="<?php echo $block->escapeHtmlAttr(__('Phone Number')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('telephone')) ?>"> </div> </div> <?php $_streetValidationClass = $this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('street'); ?> <div class="field street required"> - <label for="street_1" class="label"><span><?php /* @escapeNotVerified */ echo __('Street Address') ?></span></label> + <label for="street_1" class="label"><span><?php echo $block->escapeHtml(__('Street Address')) ?></span></label> <div class="control"> - <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getStreet(0)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address') ?>" id="street_1" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> + <input type="text" name="street[]" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getStreet(0)) ?>" title="<?php echo $block->escapeHtmlAttr(__('Street Address')) ?>" id="street_1" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> <div class="nested"> <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?> <?php for ($_i = 2, $_n = $this->helper('Magento\Customer\Helper\Address')->getStreetLines(); $_i <= $_n; $_i++): ?> <div class="field additional"> <label class="label" for="street_<?php /* @noEscape */ echo $_i ?>"> - <span><?php /* @escapeNotVerified */ echo __('Address') ?></span> + <span><?php echo $block->escapeHtml(__('Address')) ?></span> </label> <div class="control"> - <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreetLine($_i - 1)) ?>" title="<?php /* @escapeNotVerified */ echo __('Street Address %1', $_i) ?>" id="street_<?php /* @noEscape */ echo $_i ?>" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> + <input type="text" name="street[]" value="<?php echo $block->escapeHtml($block->getFormData()->getStreetLine($_i - 1)) ?>" title="<?php echo $block->escapeHtmlAttr(__('Street Address %1', $_i)) ?>" id="street_<?php /* @noEscape */ echo $_i ?>" class="input-text <?php echo $block->escapeHtmlAttr($_streetValidationClass) ?>"> </div> </div> <?php endfor; ?> @@ -81,31 +81,31 @@ </div> <div class="field required"> - <label for="city" class="label"><span><?php /* @escapeNotVerified */ echo __('City') ?></span></label> + <label for="city" class="label"><span><?php echo $block->escapeHtml(__('City')) ?></span></label> <div class="control"> - <input type="text" name="city" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getCity()) ?>" title="<?php /* @escapeNotVerified */ echo __('City') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city')) ?>" id="city"> + <input type="text" name="city" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getCity()) ?>" title="<?php echo $block->escapeHtmlAttr(__('City')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('city')) ?>" id="city"> </div> </div> <div class="field region required"> - <label for="region_id" class="label"><span><?php /* @escapeNotVerified */ echo __('State/Province') ?></span></label> + <label for="region_id" class="label"><span><?php echo $block->escapeHtml(__('State/Province')) ?></span></label> <div class="control"> - <select id="region_id" name="region_id" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" class="validate-select" style="display:none;"> - <option value=""><?php /* @escapeNotVerified */ echo __('Please select a region, state or province.') ?></option> + <select id="region_id" name="region_id" title="<?php echo $block->escapeHtmlAttr(__('State/Province')) ?>" class="validate-select" style="display:none;"> + <option value=""><?php echo $block->escapeHtml(__('Please select a region, state or province.')) ?></option> </select> - <input type="text" id="region" name="region" value="<?php echo $block->escapeHtml($block->getRegion()) ?>" title="<?php /* @escapeNotVerified */ echo __('State/Province') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>" style="display:none;"> + <input type="text" id="region" name="region" value="<?php echo $block->escapeHtml($block->getRegion()) ?>" title="<?php echo $block->escapeHtmlAttr(__('State/Province')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>" style="display:none;"> </div> </div> <div class="field zip required"> - <label for="zip" class="label"><span><?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?></span></label> + <label for="zip" class="label"><span><?php echo $block->escapeHtml(__('Zip/Postal Code')) ?></span></label> <div class="control"> - <input type="text" name="postcode" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getPostcode()) ?>" title="<?php /* @escapeNotVerified */ echo __('Zip/Postal Code') ?>" id="zip" class="input-text validate-zip-international <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode')) ?>"> + <input type="text" name="postcode" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getPostcode()) ?>" title="<?php echo $block->escapeHtmlAttr(__('Zip/Postal Code')) ?>" id="zip" class="input-text validate-zip-international <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('postcode')) ?>"> </div> </div> <div class="field country required"> - <label for="country" class="label"><span><?php /* @escapeNotVerified */ echo __('Country') ?></span></label> + <label for="country" class="label"><span><?php echo $block->escapeHtml(__('Country')) ?></span></label> <div class="control"> <?php echo $block->getCountryHtmlSelect() ?> </div> @@ -122,19 +122,19 @@ </fieldset> <?php endif; ?> - <fieldset class="fieldset create account" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Sign-in Information') ?></span></legend><br> + <fieldset class="fieldset create account" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>"> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Sign-in Information')) ?></span></legend><br> <div class="field required"> - <label for="email_address" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label for="email_address" class="label"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> - <input type="email" name="email" autocomplete="email" id="email_address" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getEmail()) ?>" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" class="input-text" data-validate="{required:true, 'validate-email':true}"> + <input type="email" name="email" autocomplete="email" id="email_address" value="<?php echo $block->escapeHtmlAttr($block->getFormData()->getEmail()) ?>" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" class="input-text" data-validate="{required:true, 'validate-email':true}"> </div> </div> <div class="field password required" data-mage-init='{"passwordStrengthIndicator": {}}'> - <label for="password" class="label"><span><?php /* @escapeNotVerified */ echo __('Password') ?></span></label> + <label for="password" class="label"><span><?php echo $block->escapeHtml(__('Password')) ?></span></label> <div class="control"> <input type="password" name="password" id="password" - title="<?php /* @escapeNotVerified */ echo __('Password') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Password')) ?>" class="input-text" data-password-min-length="<?php echo $block->escapeHtmlAttr($block->getMinimumPasswordLength()) ?>" data-password-min-character-sets="<?php echo $block->escapeHtmlAttr($block->getRequiredCharacterClassesNumber()) ?>" @@ -142,9 +142,9 @@ autocomplete="off"> <div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite"> <div id="password-strength-meter" class="password-strength-meter"> - <?php /* @escapeNotVerified */ echo __('Password Strength'); ?>: + <?php echo $block->escapeHtml(__('Password Strength')); ?>: <span id="password-strength-meter-label" data-role="password-strength-meter-label"> - <?php /* @escapeNotVerified */ echo __('No Password'); ?> + <?php echo $block->escapeHtml(__('No Password')); ?> </span> </div> </div> @@ -152,19 +152,19 @@ </div> <div class="field confirmation required"> - <label for="password-confirmation" class="label"><span><?php /* @escapeNotVerified */ echo __('Confirm Password') ?></span></label> + <label for="password-confirmation" class="label"><span><?php echo $block->escapeHtml(__('Confirm Password')) ?></span></label> <div class="control"> - <input type="password" name="password_confirmation" title="<?php /* @escapeNotVerified */ echo __('Confirm Password') ?>" id="password-confirmation" class="input-text" data-validate="{required:true, equalTo:'#password'}" autocomplete="off"> + <input type="password" name="password_confirmation" title="<?php echo $block->escapeHtmlAttr(__('Confirm Password')) ?>" id="password-confirmation" class="input-text" data-validate="{required:true, equalTo:'#password'}" autocomplete="off"> </div> </div> <?php echo $block->getChildHtml('form_additional_info'); ?> </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" class="action submit primary" title="<?php /* @escapeNotVerified */ echo __('Create an Account') ?>"><span><?php /* @escapeNotVerified */ echo __('Create an Account') ?></span></button> + <button type="submit" class="action submit primary" title="<?php echo $block->escapeHtmlAttr(__('Create an Account')) ?>"><span><?php echo $block->escapeHtml(__('Create an Account')) ?></span></button> </div> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Back') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php echo $block->escapeHtml(__('Back')) ?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml index 6b3b34fc00e..9ab5db08f18 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/resetforgottenpassword.phtml @@ -14,9 +14,9 @@ id="form-validate" class="form password reset" data-mage-init='{"validation":{}}'> - <fieldset class="fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields'); ?>"> + <fieldset class="fieldset" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')); ?>"> <div class="field password required" data-mage-init='{"passwordStrengthIndicator": {}}'> - <label class="label" for="password"><span><?php /* @escapeNotVerified */ echo __('New Password'); ?></span></label> + <label class="label" for="password"><span><?php echo $block->escapeHtml(__('New Password')); ?></span></label> <div class="control"> <input type="password" class="input-text" name="password" id="password" data-password-min-length="<?php echo $block->escapeHtmlAttr($block->getMinimumPasswordLength()) ?>" @@ -25,16 +25,16 @@ autocomplete="off"> <div id="password-strength-meter-container" data-role="password-strength-meter" aria-live="polite"> <div id="password-strength-meter" class="password-strength-meter"> - <?php /* @escapeNotVerified */ echo __('Password Strength'); ?>: + <?php echo $block->escapeHtml(__('Password Strength')); ?>: <span id="password-strength-meter-label" data-role="password-strength-meter-label"> - <?php /* @escapeNotVerified */ echo __('No Password'); ?> + <?php echo $block->escapeHtml(__('No Password')); ?> </span> </div> </div> </div> </div> <div class="field confirmation required"> - <label class="label" for="password-confirmation"><span><?php /* @escapeNotVerified */ echo __('Confirm New Password'); ?></span></label> + <label class="label" for="password-confirmation"><span><?php echo $block->escapeHtml(__('Confirm New Password')); ?></span></label> <div class="control"> <input type="password" class="input-text" name="password_confirmation" id="password-confirmation" data-validate="{required:true,equalTo:'#password'}" autocomplete="off"> </div> @@ -42,7 +42,7 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" class="action submit primary"><span><?php /* @escapeNotVerified */ echo __('Set a New Password'); ?></span></button> + <button type="submit" class="action submit primary"><span><?php echo $block->escapeHtml(__('Set a New Password')); ?></span></button> </div> </div> </form> diff --git a/app/code/Magento/Customer/view/frontend/templates/logout.phtml b/app/code/Magento/Customer/view/frontend/templates/logout.phtml index 269048d618a..4233fd95287 100644 --- a/app/code/Magento/Customer/view/frontend/templates/logout.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/logout.phtml @@ -6,7 +6,7 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> -<p><?php /* @escapeNotVerified */ echo __('You have signed out and will go to our homepage in 5 seconds.') ?></p> +<p><?php echo $block->escapeHtml(__('You have signed out and will go to our homepage in 5 seconds.')) ?></p> <script> require([ "jquery", diff --git a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml index 7bfa236eabb..ceee254897f 100644 --- a/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/newcustomer.phtml @@ -11,13 +11,13 @@ <?php if ($block->getRegistration()->isAllowed()): ?> <div class="block block-new-customer"> <div class="block-title"> - <strong id="block-new-customer-heading" role="heading" aria-level="2"><?php /* @escapeNotVerified */ echo __('New Customers') ?></strong> + <strong id="block-new-customer-heading" role="heading" aria-level="2"><?php echo $block->escapeHtml(__('New Customers')) ?></strong> </div> <div class="block-content" aria-labelledby="block-new-customer-heading"> - <p><?php /* @escapeNotVerified */ echo __('Creating an account has many benefits: check out faster, keep more than one address, track orders and more.') ?></p> + <p><?php echo $block->escapeHtml(__('Creating an account has many benefits: check out faster, keep more than one address, track orders and more.')) ?></p> <div class="actions-toolbar"> <div class="primary"> - <a href="<?php echo $block->escapeUrl($block->getCreateAccountUrl()) ?>" class="action create primary"><span><?php /* @escapeNotVerified */ echo __('Create an Account') ?></span></a> + <a href="<?php echo $block->escapeUrl($block->getCreateAccountUrl()) ?>" class="action create primary"><span><?php echo $block->escapeHtml(__('Create an Account')) ?></span></a> </div> </div> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml index c05d7c7fef8..ba589d220c3 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml @@ -9,13 +9,13 @@ /** @var \Magento\Customer\Block\Widget\Gender $block */ ?> <div class="field gender<?php if ($block->isRequired()) echo ' required' ?>"> - <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php /* @escapeNotVerified */ echo __('Gender') ?></span></label> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>"><span><?php echo $block->escapeHtml(__('Gender')) ?></span></label> <div class="control"> - <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php /* @escapeNotVerified */ echo __('Gender') ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?>> + <select id="<?php echo $block->escapeHtmlAttr($block->getFieldId('gender')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('gender')) ?>" title="<?php echo $block->escapeHtmlAttr(__('Gender')) ?>"<?php if ($block->isRequired()):?> class="validate-select" data-validate="{required:true}"<?php endif; ?>> <?php $options = $block->getGenderOptions(); ?> <?php $value = $block->getGender();?> <?php foreach ($options as $option):?> - <option value="<?php echo $block->escapeHtmlAttr($option->getValue()) ?>"<?php if ($option->getValue() == $value) echo ' selected="selected"' ?>><?php /* @escapeNotVerified */ echo __($option->getLabel()) ?></option> + <option value="<?php echo $block->escapeHtmlAttr($option->getValue()) ?>"<?php if ($option->getValue() == $value) echo ' selected="selected"' ?>><?php echo $block->escapeHtml(__($option->getLabel())) ?></option> <?php endforeach;?> </select> </div> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml index 57dcdbb3085..044500086bf 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/name.phtml @@ -29,7 +29,7 @@ $suffix = $block->showSuffix(); <?php if (($prefix || $middle || $suffix) && !$block->getNoWrap()): ?> <div class="field required fullname <?php echo $block->escapeHtmlAttr($block->getContainerClassName()) ?>"> <label for="<?php echo $block->escapeHtmlAttr($block->getFieldId('firstname')) ?>" class="label"> - <span><?php /* @escapeNotVerified */ echo __('Name') ?></span> + <span><?php echo $block->escapeHtml(__('Name')) ?></span> </label> <div class="control"> <fieldset class="fieldset fieldset-fullname"> @@ -56,7 +56,7 @@ $suffix = $block->showSuffix(); class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('prefix')) ?>" <?php if ($block->isPrefixRequired()) echo ' data-validate="{required:true}"' ?> > <?php foreach ($block->getPrefixOptions() as $_option): ?> <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getPrefix() == $_option): ?> selected="selected"<?php endif; ?>> - <?php /* @escapeNotVerified */ echo __($_option) ?> + <?php echo $block->escapeHtml(__($_option)) ?> </option> <?php endforeach; ?> </select> @@ -126,7 +126,7 @@ $suffix = $block->showSuffix(); class="<?php echo $block->escapeHtmlAttr($block->getAttributeValidationClass('suffix')) ?>" <?php if ($block->isSuffixRequired()) echo ' data-validate="{required:true}"' ?>> <?php foreach ($block->getSuffixOptions() as $_option): ?> <option value="<?php echo $block->escapeHtmlAttr($_option) ?>"<?php if ($block->getObject()->getSuffix() == $_option): ?> selected="selected"<?php endif; ?>> - <?php /* @escapeNotVerified */ echo __($_option) ?> + <?php echo $block->escapeHtml(__($_option)) ?> </option> <?php endforeach; ?> </select> diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml index 0463d33ad6e..809613a73b4 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/taxvat.phtml @@ -9,8 +9,8 @@ /** @var \Magento\Customer\Block\Widget\Taxvat $block */ ?> <div class="field taxvat<?php if ($block->isRequired()) echo ' required'; ?>"> - <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>"><span><?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?></span></label> + <label class="label" for="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>"><span><?php echo $block->escapeHtml(__('Tax/VAT number')) ?></span></label> <div class="control"> - <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php /* @escapeNotVerified */ echo __('Tax/VAT number') ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> + <input type="text" id="<?php echo $block->escapeHtmlAttr($block->getFieldId('taxvat')) ?>" name="<?php echo $block->escapeHtmlAttr($block->getFieldName('taxvat')) ?>" value="<?php echo $block->escapeHtmlAttr($block->getTaxvat()) ?>" title="<?php echo $block->escapeHtmlAttr(__('Tax/VAT number')) ?>" class="input-text <?php echo $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('taxvat')) ?>" <?php if ($block->isRequired()) echo ' data-validate="{required:true}"' ?>> </div> </div> -- GitLab From e4fb73ea6a67cd4c110a591d6e69dbb195a89809 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 23 Aug 2016 14:49:18 -0500 Subject: [PATCH 634/838] MAGETWO-54779: [GitHub] Image size for Product Watermarks can't be set #5270 - modifying js file for simplicity as per code review --- .../web/component/image-size-field.js | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js index 9f4c05214ac..37f9ef8f997 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js @@ -5,39 +5,25 @@ define([ 'jquery', - 'underscore', 'Magento_Ui/js/lib/validation/utils', 'Magento_Ui/js/form/element/abstract', 'Magento_Ui/js/lib/validation/validator' -], function ($, _, utils, Abstract, validator) { +], function ($, utils, Abstract, validator) { 'use strict'; validator.addRule( 'validate-image-size-range', function (value) { - var numValue, - dataAttrRange = /^(\d+)x(\d+)?$/, - result = false, + var dataAttrRange = /^(\d+)x(\d+)$/, m; if (utils.isEmptyNoTrim(value)) { return true; } - numValue = utils.parseNumber(value); - - if (isNaN(numValue)) { - return false; - } m = dataAttrRange.exec(value); - if (m) { - if (m.length === 3) { - result = m[1] && m[2]; - } - } - - return result; + return m && m.length === 3 && m[1] > 0 && m[2] > 0; }, $.mage.__('The value is not within the specified format eg: 200x300') ); -- GitLab From e62316b4db2cfb87291ef887241c5247aa461849 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 23 Aug 2016 14:56:35 -0500 Subject: [PATCH 635/838] MAGETWO-54779: [GitHub] Image size for Product Watermarks can't be set #5270 - modifying js file for simplicity as per code review --- .../view/adminhtml/web/component/image-size-field.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js index 37f9ef8f997..d44dd454fc1 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js @@ -23,7 +23,7 @@ define([ m = dataAttrRange.exec(value); - return m && m.length === 3 && m[1] > 0 && m[2] > 0; + return !!(m && m[1] > 0 && m[2] > 0); }, $.mage.__('The value is not within the specified format eg: 200x300') ); @@ -33,11 +33,10 @@ define([ /** * Checks for relevant value * - * @param {*} value * @returns {Boolean} */ - isRangeCorrect: function (value) { - return validator('validate-image-size-range', value); + isRangeCorrect: function () { + return validator('validate-image-size-range', this.value()).passed; } }); }); -- GitLab From 0272235c3a006e377318590484311efa4a2fcc5c Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 23 Aug 2016 15:02:55 -0500 Subject: [PATCH 636/838] MAGETWO-57233: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../view/adminhtml/templates/default.phtml | 13 +++---- .../view/frontend/templates/default.phtml | 15 ++++---- .../view/frontend/templates/form.phtml | 29 ++++++++------- .../frontend/templates/html/notices.phtml | 8 ++--- .../view/frontend/templates/remember_me.phtml | 14 ++++---- .../Rss/view/frontend/templates/feeds.phtml | 11 +++--- .../view/frontend/templates/send.phtml | 36 +++++++++---------- 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index 1aceb9ff95d..2972080063c 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -6,13 +6,14 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Captcha\Block\Captcha\DefaultCaptcha $block */ + +/** @var \Magento\Captcha\Model\DefaultModel $captcha */ +$captcha = $block->getCaptchaModel(); ?> -<?php /* @var $captcha \Magento\Captcha\Model\DefaultModel */ ?> -<?php /* @var $block \Magento\Captcha\Block\Captcha\DefaultCaptcha */ ?> -<?php $captcha = $block->getCaptchaModel() ?> <div class="admin__field _required"> <label for="captcha" class="admin__field-label"> - <span><?php /* @escapeNotVerified */ echo __('Please enter the letters from the image') ?></span> + <span><?php echo $block->escapeHtml(__('Please enter the letters from the image')) ?></span> </label> <div class="admin__field-control"> <input @@ -23,7 +24,7 @@ data-validate="{required:true}"/> <?php if ($captcha->isCaseSensitive()) :?> <div class="admin__field-note"> - <span><?php /* @escapeNotVerified */ echo __('<strong>Attention</strong>: Captcha is case sensitive.') ?></span> + <span><?php echo $block->escapeHtml(__('<strong>Attention</strong>: Captcha is case sensitive.'), ['strong']) ?></span> </div> <?php endif; ?> </div> @@ -33,7 +34,7 @@ id="captcha-reload" class="captcha-reload" src="<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Captcha::reload.png')) ?>" - alt="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"/> + alt="<?php echo $block->escapeHtmlAttr(__('Reload captcha')) ?>"/> <img id="<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" width="<?php /* @noEscape */ echo (float) $block->getImgWidth() ?>" diff --git a/app/code/Magento/Captcha/view/frontend/templates/default.phtml b/app/code/Magento/Captcha/view/frontend/templates/default.phtml index 4046b5f96ec..92c008a0e18 100644 --- a/app/code/Magento/Captcha/view/frontend/templates/default.phtml +++ b/app/code/Magento/Captcha/view/frontend/templates/default.phtml @@ -6,12 +6,13 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Captcha\Block\Captcha\DefaultCaptcha $block */ + +/** @var \Magento\Captcha\Model\DefaultModel $captcha */ +$captcha = $block->getCaptchaModel(); ?> -<?php /* @var $captcha \Magento\Captcha\Model\DefaultModel */ ?> -<?php /* @var $block \Magento\Captcha\Block\Captcha\DefaultCaptcha */ ?> -<?php $captcha = $block->getCaptchaModel() ?> <div class="field captcha required" role="<?php echo $block->escapeHtmlAttr($block->getFormId())?>"> - <label for="captcha_<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Please type the letters below')?></span></label> + <label for="captcha_<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" class="label"><span><?php echo $block->escapeHtml(__('Please type the letters below')) ?></span></label> <div class="control captcha"> <input name="<?php echo $block->escapeHtmlAttr(\Magento\Captcha\Helper\Data::INPUT_NAME_FIELD_VALUE) ?>[<?php echo $block->escapeHtmlAttr($block->getFormId())?>]" type="text" class="input-text required-entry" data-validate="{required:true}" id="captcha_<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>" /> <div class="nested"> @@ -22,13 +23,13 @@ "imageLoader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-2.gif')) ?>", "type": "<?php echo $block->escapeHtmlAttr($block->getFormId()) ?>"}}'> <div class="control captcha-image"> - <img alt="<?php /* @escapeNotVerified */ echo __('Please type the letters below')?>" class="captcha-img" height="<?php /* @noEscape */ echo (float) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>"/> - <button type="button" class="action reload captcha-reload" title="<?php /* @escapeNotVerified */ echo __('Reload captcha') ?>"><span><?php /* @escapeNotVerified */ echo __('Reload captcha') ?></span></button> + <img alt="<?php echo $block->escapeHtmlAttr(__('Please type the letters below')) ?>" class="captcha-img" height="<?php /* @noEscape */ echo (float) $block->getImgHeight() ?>" src="<?php echo $block->escapeUrl($captcha->getImgSrc()) ?>"/> + <button type="button" class="action reload captcha-reload" title="<?php echo $block->escapeHtmlAttr(__('Reload captcha')) ?>"><span><?php echo $block->escapeHtml(__('Reload captcha')) ?></span></button> </div> </div> <?php if ($captcha->isCaseSensitive()) :?> <div class="captcha-note note"> - <?php /* @escapeNotVerified */ echo __('<strong>Attention</strong>: Captcha is case sensitive.') ?> + <?php echo $block->escapeHtml(__('<strong>Attention</strong>: Captcha is case sensitive.'), ['strong']) ?> </div> <?php endif; ?> </div> diff --git a/app/code/Magento/Contact/view/frontend/templates/form.phtml b/app/code/Magento/Contact/view/frontend/templates/form.phtml index aa8d6975389..6322c5b2fe5 100644 --- a/app/code/Magento/Contact/view/frontend/templates/form.phtml +++ b/app/code/Magento/Contact/view/frontend/templates/form.phtml @@ -5,40 +5,39 @@ */ // @codingStandardsIgnoreFile - +/** @var \Magento\Contact\Block\ContactForm $block */ ?> -<?php /** @var $block \Magento\Contact\Block\ContactForm */ ?> <form class="form contact" action="<?php echo $block->escapeUrl($block->getFormAction()); ?>" id="contact-form" method="post" - data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" + data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>" data-mage-init='{"validation":{}}'> <fieldset class="fieldset"> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Write Us') ?></span></legend><br /> - <div class="field note no-label"><?php /* @escapeNotVerified */ echo __('Jot us a note and we’ll get back to you as quickly as possible.') ?></div> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Write Us')) ?></span></legend><br /> + <div class="field note no-label"><?php echo $block->escapeHtml(__('Jot us a note and we’ll get back to you as quickly as possible.')) ?></div> <div class="field name required"> - <label class="label" for="name"><span><?php /* @escapeNotVerified */ echo __('Name') ?></span></label> + <label class="label" for="name"><span><?php echo $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> - <input name="name" id="name" title="<?php /* @escapeNotVerified */ echo __('Name') ?>" value="<?php echo $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('name') ?: $this->helper('Magento\Contact\Helper\Data')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/> + <input name="name" id="name" title="<?php echo $block->escapeHtmlAttr(__('Name')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('name') ?: $this->helper('Magento\Contact\Helper\Data')->getUserName()) ?>" class="input-text" type="text" data-validate="{required:true}"/> </div> </div> <div class="field email required"> - <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label class="label" for="email"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> - <input name="email" id="email" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" value="<?php echo $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('email') ?: $this->helper('Magento\Contact\Helper\Data')->getUserEmail()) ?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/> + <input name="email" id="email" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('email') ?: $this->helper('Magento\Contact\Helper\Data')->getUserEmail()) ?>" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/> </div> </div> <div class="field telephone"> - <label class="label" for="telephone"><span><?php /* @escapeNotVerified */ echo __('Phone Number') ?></span></label> + <label class="label" for="telephone"><span><?php echo $block->escapeHtml(__('Phone Number')) ?></span></label> <div class="control"> - <input name="telephone" id="telephone" title="<?php /* @escapeNotVerified */ echo __('Phone Number') ?>" value="<?php echo $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('telephone')) ?>" class="input-text" type="text" /> + <input name="telephone" id="telephone" title="<?php echo $block->escapeHtmlAttr(__('Phone Number')) ?>" value="<?php echo $block->escapeHtmlAttr($this->helper('Magento\Contact\Helper\Data')->getPostValue('telephone')) ?>" class="input-text" type="text" /> </div> </div> <div class="field comment required"> - <label class="label" for="comment"><span><?php /* @escapeNotVerified */ echo __('What’s on your mind?') ?></span></label> + <label class="label" for="comment"><span><?php echo $block->escapeHtml(__('What’s on your mind?')) ?></span></label> <div class="control"> - <textarea name="comment" id="comment" title="<?php /* @escapeNotVerified */ echo __('What’s on your mind?') ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"><?php echo $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('comment')) ?></textarea> + <textarea name="comment" id="comment" title="<?php echo $block->escapeHtmlAttr(__('What’s on your mind?')) ?>" class="input-text" cols="5" rows="3" data-validate="{required:true}"><?php echo $block->escapeHtml($this->helper('Magento\Contact\Helper\Data')->getPostValue('comment')) ?></textarea> </div> </div> <?php echo $block->getChildHtml('form.additional.info'); ?> @@ -46,8 +45,8 @@ <div class="actions-toolbar"> <div class="primary"> <input type="hidden" name="hideit" id="hideit" value="" /> - <button type="submit" title="<?php /* @escapeNotVerified */ echo __('Submit') ?>" class="action submit primary"> - <span><?php /* @escapeNotVerified */ echo __('Submit') ?></span> + <button type="submit" title="<?php echo $block->escapeHtmlAttr(__('Submit')) ?>" class="action submit primary"> + <span><?php echo $block->escapeHtml(__('Submit')) ?></span> </button> </div> </div> diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index cbf1d3ad2b2..d34214a3f7b 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -12,12 +12,12 @@ <div class="message global cookie" id="notice-cookie-block" style="display: none"> <div class="content"> <p> - <strong><?php /* @escapeNotVerified */ echo __('We use cookies to make your experience better.') ?></strong> - <span><?php /* @escapeNotVerified */ echo __('To comply with the new e-Privacy directive, we need to ask for your consent to set the cookies.') ?></span> - <?php /* @escapeNotVerified */ echo __('<a href="%1">Learn more</a>.', $block->getPrivacyPolicyLink()) ?></p> + <strong><?php echo $block->escapeHtml(__('We use cookies to make your experience better.')) ?></strong> + <span><?php echo $block->escapeHtml(__('To comply with the new e-Privacy directive, we need to ask for your consent to set the cookies.')) ?></span> + <?php echo $block->escapeHtml(__('<a href="%1">Learn more</a>.', $block->getPrivacyPolicyLink()), ['a']) ?></p> <div class="actions"> <button id="btn-cookie-allow" class="action allow primary"> - <span><?php /* @escapeNotVerified */ echo __('Allow Cookies');?></span> + <span><?php echo $block->escapeHtml(__('Allow Cookies')); ?></span> </button> </div> </div> diff --git a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml index 40cbb7dc64b..f4b3ec41cb3 100644 --- a/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml +++ b/app/code/Magento/Persistent/view/frontend/templates/remember_me.phtml @@ -6,23 +6,21 @@ // @codingStandardsIgnoreFile -?> -<?php /** * Customer "Remember Me" template - * - * @var $block \Magento\Persistent\Block\Form\Remember */ +/** @var \Magento\Persistent\Block\Form\Remember $block */ + ?> <div id="remember-me-box" class="field choice persistent"> <?php $rememberMeId = 'remember_me' . $block->getRandomString(10); ?> - <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php /* @escapeNotVerified */ echo __('Remember Me') ?>" /> - <label for="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>" class="label"><span><?php /* @escapeNotVerified */ echo __('Remember Me') ?></span></label> + <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>"<?php if ($block->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php echo $block->escapeHtmlAttr(__('Remember Me')) ?>" /> + <label for="<?php echo $block->escapeHtmlAttr($rememberMeId); ?>" class="label"><span><?php echo $block->escapeHtml(__('Remember Me')) ?></span></label> <span class="tooltip wrapper"> - <a class="link tooltip toggle" href="#"><?php /* @escapeNotVerified */ echo __('What\'s this?') ?></a> + <a class="link tooltip toggle" href="#"><?php echo $block->escapeHtml(__('What\'s this?')) ?></a> <span class="tooltip content"> - <?php /* @escapeNotVerified */ echo __('Check "Remember Me" to access your shopping cart on this computer even if you are not signed in.')?> + <?php echo $block->escapeHtml(__('Check "Remember Me" to access your shopping cart on this computer even if you are not signed in.')) ?> </span> </span> </div> diff --git a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml index 7c7c3a48390..f1074799dac 100644 --- a/app/code/Magento/Rss/view/frontend/templates/feeds.phtml +++ b/app/code/Magento/Rss/view/frontend/templates/feeds.phtml @@ -6,18 +6,19 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Rss\Block\Feeds $block */ + ?> -<?php /** @var $block \Magento\Rss\Block\Feeds */ ?> <table class="data table rss"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Feed'); ?></caption> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Feed')); ?></caption> <tbody> - <th colspan="2" scope="col"><?php /* @escapeNotVerified */ echo __('Miscellaneous Feeds') ?></th> + <th colspan="2" scope="col"><?php echo $block->escapeHtml(__('Miscellaneous Feeds')) ?></th> <?php foreach ($block->getFeeds() as $feed): ?> <?php if (!isset($feed['group'])): ?> <tr> <td class="col feed"><?php echo $block->escapeHtml($feed['label']) ?></td> <td class="col action"> - <a href="<?php echo $block->escapeUrl($feed['link']) ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> + <a href="<?php echo $block->escapeUrl($feed['link']) ?>" class="action get"><span><?php echo $block->escapeHtml(__('Get Feed')); ?></span></a> </td> </tr> <?php else: ?> @@ -26,7 +27,7 @@ <tr> <td class="col feed"><?php echo $block->escapeHtml($item['label']) ?></td> <td class="col action"> - <a href="<?php echo $block->escapeUrl($item['link']) ?>" class="action get"><span><?php /* @escapeNotVerified */ echo __('Get Feed'); ?></span></a> + <a href="<?php echo $block->escapeUrl($item['link']) ?>" class="action get"><span><?php echo $block->escapeHtml(__('Get Feed')); ?></span></a> </td> </tr> <?php endforeach; ?> diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index edae5a01a31..4f52f5026bb 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -8,9 +8,9 @@ /** * Send to friend form - * - * @var $block \Magento\SendFriend\Block\Send */ +/** @var \Magento\SendFriend\Block\Send $block */ + ?> <script id="add-recipient-tmpl" type="text/x-magento-template"> <div class="actions-toolbar"> @@ -23,17 +23,17 @@ </div> <fieldset class="fieldset"> <div class="field name required"> - <label for="recipients-name<%- data._index_ %>" class="label"><span><?php /* @escapeNotVerified */ echo __('Name')?></span></label> + <label for="recipients-name<%- data._index_ %>" class="label"><span><?php echo $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> - <input name="recipients[name][<%- data._index_ %>]" type="text" title="<?php /* @escapeNotVerified */ echo __('Name') ?>" class="input-text" + <input name="recipients[name][<%- data._index_ %>]" type="text" title="<?php echo $block->escapeHtmlAttr(__('Name')) ?>" class="input-text" id="recipients-name<%- data._index_ %>" data-validate="{required:true}"/> </div> </div> <div class="field email required"> - <label for="recipients-email<%- data._index_ %>" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label for="recipients-email<%- data._index_ %>" class="label"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> - <input name="recipients[email][<%- data._index_ %>]" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" + <input name="recipients[email][<%- data._index_ %>]" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" id="recipients-email<%- data._index_ %>" type="email" class="input-text" data-validate="{required:true, 'validate-email':true}"/> </div> @@ -54,31 +54,31 @@ "addRowBtn":"#add-recipient-button", "additionalRowClass":"additional"}, "validation":{}}' - class="form send friend" data-hasRequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"> + class="form send friend" data-hasRequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>"> <fieldset class="fieldset sender" id="sender_options"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Sender') ?></span></legend> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Sender')) ?></span></legend> <br> <div class="field sender required"> - <label for="sender-name" class="label"><span><?php /* @escapeNotVerified */ echo __('Name') ?></span></label> + <label for="sender-name" class="label"><span><?php echo $block->escapeHtml(__('Name')) ?></span></label> <div class="control"> <input name="sender[name]" value="<?php echo $block->escapeHtmlAttr($block->getUserName()) ?>" - title="<?php /* @escapeNotVerified */ echo __('Name') ?>" id="sender-name" type="text" class="input-text" + title="<?php echo $block->escapeHtmlAttr(__('Name')) ?>" id="sender-name" type="text" class="input-text" data-validate="{required:true}"/> </div> </div> <div class="field email required"> - <label for="sender-email" class="label"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label> + <label for="sender-email" class="label"><span><?php echo $block->escapeHtml(__('Email')) ?></span></label> <div class="control"> <input name="sender[email]" value="<?php echo $block->escapeHtmlAttr($block->getEmail()) ?>" - title="<?php /* @escapeNotVerified */ echo __('Email') ?>" id="sender-email" type="text" class="input-text" + title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" id="sender-email" type="text" class="input-text" data-validate="{required:true, 'validate-email':true}"/> </div> </div> <div class="field text required"> - <label for="sender-message" class="label"><span><?php /* @escapeNotVerified */ echo __('Message') ?></span></label> + <label for="sender-message" class="label"><span><?php echo $block->escapeHtml(__('Message')) ?></span></label> <div class="control"> <textarea name="sender[message]" class="input-text" id="sender-message" cols="3" rows="3" data-validate="{required:true}"><?php echo $block->escapeHtml($block->getMessage()) ?></textarea> @@ -88,19 +88,19 @@ <fieldset class="fieldset recipients"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Invitee') ?></span></legend> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Invitee')) ?></span></legend> <br /> <div id="recipients-options"></div> <?php if ($block->getMaxRecipients()): ?> <div id="max-recipient-message" style="display: none;" class="message notice limit" role="alert"> - <span><?php /* @escapeNotVerified */ echo __('Maximum %1 email addresses allowed.', $block->getMaxRecipients()) ?></span> + <span><?php echo $block->escapeHtml(__('Maximum %1 email addresses allowed.', $block->getMaxRecipients())) ?></span> </div> <?php endif; ?> <div class="actions-toolbar"> <div class="secondary"> <?php if (1 < $block->getMaxRecipients()): ?> <button type="button" id="add-recipient-button" class="action add"> - <span><?php /* @escapeNotVerified */ echo __('Add Invitee') ?></span></button> + <span><?php echo $block->escapeHtml(__('Add Invitee')) ?></span></button> <?php endif; ?> </div> </div> @@ -109,10 +109,10 @@ <div class="primary"> <button type="submit" class="action submit primary"<?php if (!$block->canSend()): ?> disabled="disabled"<?php endif ?>> - <span><?php /* @escapeNotVerified */ echo __('Send Email') ?></span></button> + <span><?php echo $block->escapeHtml(__('Send Email')) ?></span></button> </div> <div class="secondary"> - <a class="action back" href="#" role="back"><span><?php /* @escapeNotVerified */ echo __('Back') ?></span></a> + <a class="action back" href="#" role="back"><span><?php echo $block->escapeHtml(__('Back')) ?></span></a> </div> </div> </form> -- GitLab From 6625e8c5484f3e469dbcc0c0719836fa5d0e896c Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 23 Aug 2016 15:22:01 -0500 Subject: [PATCH 637/838] MAGETWO-54779: [GitHub] Image size for Product Watermarks can't be set #5270 - fixing error phrase --- app/code/Magento/Catalog/i18n/en_US.csv | 2 +- .../Catalog/view/adminhtml/web/component/image-size-field.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv index 6b8a2bc607d..a1f1b2e5beb 100644 --- a/app/code/Magento/Catalog/i18n/en_US.csv +++ b/app/code/Magento/Catalog/i18n/en_US.csv @@ -700,7 +700,7 @@ Image,Image "Allowed file types: jpeg, gif, png.","Allowed file types: jpeg, gif, png." "Image Opacity","Image Opacity" "Example format: 200x300.","Example format: 200x300." -"The value is not within the specified format eg: 200x300","The value is not within the specified format eg: 200x300" +"This value does not follow the specified format (for example, 200X300).","This value does not follow the specified format (for example, 200X300)." "Image Position","Image Position" Small,Small "Attribute Label","Attribute Label" diff --git a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js index d44dd454fc1..b330ccfd8c1 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js @@ -25,7 +25,7 @@ define([ return !!(m && m[1] > 0 && m[2] > 0); }, - $.mage.__('The value is not within the specified format eg: 200x300') + $.mage.__('This value does not follow the specified format (for example, 200X300).') ); return Abstract.extend({ -- GitLab From dd3c3c7c149b79124806cef05e865ee10fe594f1 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 23 Aug 2016 15:51:54 -0500 Subject: [PATCH 638/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 66 +++++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fe88e2b0792..c082fff7f53 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -31,10 +31,21 @@ class Escaper } } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { + $result = $this->filterHtmlTagsAndAttributes($data, $allowedTags); + /* $allowed = implode('|', $allowedTags); - $result = preg_replace('/<([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)>/si', '##$1$2$3##', $data); + $result = preg_replace( + '/<([\/\s\r\n]*)(' . $allowed . '[^>]*)([\/\s\r\n]*)>/si', + '##$1$2$3##', + $data + ); $result = htmlspecialchars($result, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); - $result = preg_replace('/##([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)##/si', '<$1$2$3>', $result); + $result = preg_replace( + '/##([\/\s\r\n]*)(' . $allowed . '[^##]*)([\/\s\r\n]*)##/si', + '<$1$2$3>', + $result + ); + */ } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } @@ -44,6 +55,57 @@ class Escaper return $result; } + /** + * Removes not allowed HTML tags and attributes from string + * + * @param string $string + * @param string[] $allowedTags + * @return string + */ + private function filterHtmlTagsAndAttributes($string, $allowedTags) + { + $wrapperElementId = uniqid(); + + $dom = new \DOMDocument(); + $dom->loadHTML('<span id="' . $wrapperElementId . '">' . $string . '</span>'); + $xpath = new \DOMXPath($dom); + + $nodes = $xpath->query('//node()[text() and name() != \'html\' and name() != \'body\' and name() != \'' + . implode('\' and name() != \'', $allowedTags) . '\']'); + foreach ($nodes as $node) { + $node->parentNode->removeChild($node); + } + + $nodes = $xpath->query('//@*[name() != \'' . implode('\' and name() != \'', ['id', 'class', 'href']) . '\']'); + foreach ($nodes as $node) { + $node->parentNode->removeAttribute($node->nodeName); + } + + $nodes = $xpath->query('//text()'); + foreach ($nodes as $node) { + $node->textContent = $this->escapeHtml($node->textContent); + } + + $nodes = $xpath->query('//@*'); + foreach ($nodes as $node) { + $value = $node->parentNode->getAttribute($node->nodeName); + if ($node->nodeName == 'href') { + $value = $this->escapeUrl($value); + } else { + $value = $this->escapeHtmlAttr($value); + } + $node->parentNode->setAttribute($node->nodeName, $value); + } + + $result = mb_convert_encoding( + $dom->saveHTML($dom->getElementById($wrapperElementId)), + 'UTF-8', + 'HTML-ENTITIES' + ); + + return substr($result, 25, strlen($result)-32); + } + /** * Escape a string for the HTML attribute context * -- GitLab From addb46f7c0237c9b73c2e46740b177af6e64c577 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 23 Aug 2016 17:11:45 -0500 Subject: [PATCH 639/838] MAGETWO-54785: [GitHub] State/Province field doesn't show as required on the add new address page - fixing eslint and jscs errors --- .../view/frontend/web/js/region-updater.js | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index 92c8b08bee6..e06b8922b22 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -25,6 +25,10 @@ define([ isMultipleCountriesAllowed: true }, + /** + * + * @private + */ _create: function () { this._initCountryElement(); @@ -43,12 +47,18 @@ define([ }, this)); }, - _initCountryElement: function() { + /** + * + * @private + */ + _initCountryElement: function () { + if (this.options.isMultipleCountriesAllowed) { this.element.parents('div.field').show(); this.element.on('change', $.proxy(function (e) { this._updateRegion($(e.target).val()); }, this)); + if (this.options.isCountryRequired) { this.element.addClass('required-entry'); this.element.parents('div.field').addClass('required'); @@ -60,6 +70,7 @@ define([ /** * Remove options from dropdown list + * * @param {Object} selectElement - jQuery object for dropdown list * @private */ @@ -113,7 +124,7 @@ define([ * @private */ _clearError: function () { - if (this.options.clearError && typeof (this.options.clearError) === 'function') { + if (this.options.clearError && typeof this.options.clearError === 'function') { this.options.clearError.call(this); } else { if (!this.options.form) { @@ -131,8 +142,10 @@ define([ $(this.options.postcodeId).removeClass('mage-error').parent().find('[generated]').remove(); } }, + /** * Update dropdown list based on the country selected + * * @param {String} country - 2 uppercase letter for country code * @private */ @@ -188,7 +201,7 @@ define([ regionInput.attr('disabled', 'disabled'); } requiredLabel.removeClass('required'); - regionInput.removeClass('required-entry') + regionInput.removeClass('required-entry'); } regionList.removeClass('required-entry').hide(); @@ -214,10 +227,11 @@ define([ * @private */ _checkRegionRequired: function (country) { - this.options.isRegionRequired = false; var self = this; + + this.options.isRegionRequired = false; $.each(this.options.regionJson.config.regions_required, function (index, elem) { - if (elem == country) { + if (elem === country) { self.options.isRegionRequired = true; } }); -- GitLab From ce6df998c4a7af3613b589bcefaf6edf665e5a58 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Tue, 23 Aug 2016 14:32:53 -0500 Subject: [PATCH 640/838] MAGETWO-57232: Eliminate @escapeNotVerified in Wishlist Module - updated templates --- .../customer/edit/tab/wishlist.phtml | 2 +- .../frontend/templates/button/share.phtml | 4 +-- .../frontend/templates/button/tocart.phtml | 4 +-- .../frontend/templates/button/update.phtml | 4 +-- .../renderer/actions/move_to_wishlist.phtml | 2 +- .../catalog/product/list/addto/wishlist.phtml | 6 ++-- .../catalog/product/view/addto/wishlist.phtml | 2 +- .../view/frontend/templates/email/items.phtml | 4 +-- .../frontend/templates/item/column/cart.phtml | 14 +++++----- .../templates/item/column/comment.phtml | 4 +-- .../frontend/templates/item/column/edit.phtml | 2 +- .../templates/item/column/remove.phtml | 4 +-- .../templates/item/configure/addto.phtml | 4 +-- .../item/configure/addto/wishlist.phtml | 2 +- .../view/frontend/templates/item/list.phtml | 2 +- .../messages/addProductSuccessMessage.phtml | 3 +- .../frontend/templates/options_list.phtml | 4 +-- .../view/frontend/templates/rss/email.phtml | 2 +- .../frontend/templates/rss/wishlist.phtml | 2 +- .../view/frontend/templates/shared.phtml | 28 +++++++++---------- .../view/frontend/templates/sharing.phtml | 18 ++++++------ .../view/frontend/templates/sidebar.phtml | 14 +++++----- .../view/frontend/templates/view.phtml | 4 +-- 23 files changed, 68 insertions(+), 67 deletions(-) diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index 63377fcbbbe..d360c5dfc24 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -50,7 +50,7 @@ var self = this; confirm({ - content: '<?php /* @escapeNotVerified */ echo __('Are you sure you want to remove this item?') ?>', + content: '<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure you want to remove this item?'))) ?>', actions: { confirm: function () { self.reload('&delete=' + itemId); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml index 51dc0d7b3db..4275ec4f302 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/share.phtml @@ -9,7 +9,7 @@ /** @var \Magento\Wishlist\Block\Customer\Wishlist\Button $block */ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->getShared() < $block->getConfig()->getSharingEmailLimit()): ?> - <button type="submit" name="save_and_share" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action share"> - <span><?php /* @escapeNotVerified */ echo __('Share Wish List') ?></span> + <button type="submit" name="save_and_share" title="<?php echo $block->escapeHtmlAttr(__('Share Wish List')) ?>" class="action share"> + <span><?php echo $block->escapeHtml(__('Share Wish List')) ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml index 3f2984eac3f..0e910eecac5 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/tocart.phtml @@ -10,7 +10,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount() && $block->getWishlist()->isSalable()): ?> - <button type="button" data-role="all-tocart" title="<?php /* @escapeNotVerified */ echo __('Add All to Cart') ?>" class="action tocart"> - <span><?php /* @escapeNotVerified */ echo __('Add All to Cart') ?></span> + <button type="button" data-role="all-tocart" title="<?php echo $block->escapeHtmlAttr(__('Add All to Cart')) ?>" class="action tocart"> + <span><?php echo $block->escapeHtml(__('Add All to Cart')) ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml index dfb24bde08b..189d0304097 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/button/update.phtml @@ -10,7 +10,7 @@ ?> <?php if ($block->getWishlist()->getItemsCount()): ?> - <button type="submit" name="do" title="<?php /* @escapeNotVerified */ echo __('Update Wish List') ?>" class="action update"> - <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> + <button type="submit" name="do" title="<?php echo $block->escapeHtmlAttr(__('Update Wish List')) ?>" class="action update"> + <span><?php echo $block->escapeHtml(__('Update Wish List')) ?></span> </button> <?php endif;?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml index 26d35fd8cfc..cbe3553251f 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/cart/item/renderer/actions/move_to_wishlist.phtml @@ -12,6 +12,6 @@ <a href="#" data-post='<?php /* @noEscape */ echo $block->getMoveFromCartParams(); ?>' class="use-ajax action action-towishlist"> - <span><?php /* @escapeNotVerified */ echo __('Move to Wishlist'); ?></span> + <span><?php echo $block->escapeHtml(__('Move to Wishlist')); ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index 4534fdc5653..5e743c0af45 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -11,11 +11,11 @@ <?php if ($block->getWishlistHelper()->isAllow()): ?> <a href="#" class="action towishlist" - title="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>" - aria-label="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>" + title="<?php echo $block->escapeHtmlAttr($block->escapeHtmlAttr(__('Add to Wish List'))); ?>" + aria-label="<?php echo $block->escapeHtmlAttr(__('Add to Wish List')); ?>" data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' data-action="add-to-wishlist" role="button"> - <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> + <span><?php echo $block->escapeHtml(__('Add to Wish List')) ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml index 104d56f72dd..3c238e3c865 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/view/addto/wishlist.phtml @@ -12,7 +12,7 @@ <a href="#" class="action towishlist" data-post='<?php /* @noEscape */ echo $block->getWishlistParams(); ?>' - data-action="add-to-wishlist"><span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span></a> + data-action="add-to-wishlist"><span><?php echo $block->escapeHtml(__('Add to Wish List')) ?></span></a> <?php endif; ?> <script type="text/x-magento-init"> { diff --git a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml index 003aa4db62d..24b7f92d198 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/email/items.phtml @@ -31,13 +31,13 @@ </p> <?php if ($block->hasDescription($item)): ?> <p> - <strong><?= /* @escapeNotVerified */ __('Comment') ?>:</strong> + <strong><?= $block->escapeHtml(__('Comment')) ?>:</strong> <br/><?= /* @noEscape */ $block->getEscapedDescription($item) ?> </p> <?php endif; ?> <p> <a href="<?= $block->escapeUrl($block->getProductUrl($_product)) ?>"> - <?= /* @escapeNotVerified */ __('View Product') ?> + <?= $block->escapeHtml(__('View Product')) ?> </a> </p> </td> 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 1c041e67822..a9b51f9a03d 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 @@ -19,7 +19,7 @@ $product = $item->getProduct(); <fieldset class="fieldset"> <?php if ($item->canHaveQty() && $product->isVisibleInSiteVisibility()): ?> <div class="field qty"> - <label class="label" for="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label> + <label class="label" for="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]"><span><?php echo $block->escapeHtml(__('Qty')) ?></span></label> <div class="control"> <input type="number" data-role="qty" id="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]" class="input-text qty" data-validate="{'required-number':true,'validate-greater-than-zero':true}" name="qty[<?php echo $block->escapeHtmlAttr($item->getId()) ?>]" value="<?php /* @noEscape */ echo (int)($block->getAddToCartQty($item) * 1) ?>"> @@ -29,19 +29,19 @@ $product = $item->getProduct(); <?php if ($product->isSaleable()): ?> <div class="product-item-actions"> <div class="actions-primary"> - <button type="button" data-role="tocart" data-post='<?php /* @noEscape */ echo $block->getItemAddToCartParams($item)?>' title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>" data-item-id="<?php echo $block->escapeHtmlAttr($item->getId())?>" class="action tocart primary"> - <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> + <button type="button" data-role="tocart" data-post='<?php /* @noEscape */ echo $block->getItemAddToCartParams($item)?>' title="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>" data-item-id="<?php echo $block->escapeHtmlAttr($item->getId())?>" class="action tocart primary"> + <span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span> </button> </div> </div> <?php else: ?> <?php if ($product->getIsSalable()): ?> - <p class="available stock" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>"> - <span><?php /* @escapeNotVerified */ echo __('In stock') ?></span> + <p class="available stock" title="<?php echo $block->escapeHtmlAttr(__('Availability')) ?>"> + <span><?php echo $block->escapeHtml(__('In stock')) ?></span> </p> <?php else: ?> - <p class="unavailable stock" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>"> - <span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span> + <p class="unavailable stock" title="<?php echo $block->escapeHtmlAttr(__('Availability')) ?>"> + <span><?php echo $block->escapeHtml(__('Out of stock')) ?></span> </p> <?php endif; ?> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml index 66f56f66a07..8c10c0248e8 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/comment.phtml @@ -14,9 +14,9 @@ $item = $block->getItem(); <div class="field comment-box"> <label class="label" for="product-item-comment-<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Comment') ?></span> + <span><?php echo $block->escapeHtml(__('Comment')) ?></span> </label> <div class="control"> - <textarea id="product-item-comment-<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>" placeholder="<?php /* @noEscape */ echo $this->helper('Magento\Wishlist\Helper\Data')->defaultCommentString() ?>" name="description[<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>]" title="<?php /* @escapeNotVerified */ echo __('Comment') ?>" class="product-item-comment"><?php echo($block->escapeHtml($item->getDescription())) ?></textarea> + <textarea id="product-item-comment-<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>" placeholder="<?php /* @noEscape */ echo $this->helper('Magento\Wishlist\Helper\Data')->defaultCommentString() ?>" name="description[<?php echo $block->escapeHtmlAttr($item->getWishlistItemId()) ?>]" title="<?php echo $block->escapeHtmlAttr(__('Comment')) ?>" class="product-item-comment"><?php echo($block->escapeHtml($item->getDescription())) ?></textarea> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml index d7e523931c0..7381bfa5326 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/edit.phtml @@ -15,6 +15,6 @@ $product = $item->getProduct(); <?php if ($product->isVisibleInSiteVisibility()): ?> <a class="action edit" href="<?php echo $block->escapeUrl($block->getItemConfigureUrl($item)) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Edit') ?></span> + <span><?php echo $block->escapeHtml(__('Edit')) ?></span> </a> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml index 50b61d61457..07151547dcc 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/column/remove.phtml @@ -9,6 +9,6 @@ /* @var \Magento\Wishlist\Block\Customer\Wishlist\Item\Column\Remove $block */ ?> -<a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php /* @escapeNotVerified */ echo __('Remove Item') ?>" class="btn-remove action delete"> - <span><?php /* @escapeNotVerified */ echo __('Remove item');?></span> +<a href="#" data-role="remove" data-post-remove='<?php /* @noEscape */ echo $block->getItemRemoveParams($block->getItem()); ?>' title="<?php echo $block->escapeHtmlAttr(__('Remove Item')) ?>" class="btn-remove action delete"> + <span><?php echo $block->escapeHtml(__('Remove item'));?></span> </a> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml index 26a28b2c3bd..ddc2dceff81 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto.phtml @@ -12,14 +12,14 @@ <div class="product-addto-links" data-role="add-to-links"> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> - <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> + <span><?php echo $block->escapeHtml(__('Update Wish List')) ?></span> </a> <?php endif; ?> <?php $_product = $block->getProduct(); ?> <?php $_compareUrl = $this->helper('Magento\Catalog\Helper\Product\Compare')->getAddUrl($_product); ?> <?php if ($_compareUrl) : ?> <a href="<?php echo $block->escapeUrl($_compareUrl) ?>" class="action tocompare"> - <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span> + <span><?php echo $block->escapeHtml(__('Add to Compare')) ?></span> </a> <?php endif; ?> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml index 9d721e9a50c..0441614bfc9 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/configure/addto/wishlist.phtml @@ -10,7 +10,7 @@ ?> <?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()) : ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getUpdateParams(); ?>' class="action towishlist updated" data-action="add-to-wishlist"> - <span><?php /* @escapeNotVerified */ echo __('Update Wish List') ?></span> + <span><?php echo $block->escapeHtml(__('Update Wish List')) ?></span> </a> <?php endif; ?> <script type="text/x-magento-init"> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml index 9850f8fa7ea..1caca046365 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/item/list.phtml @@ -28,7 +28,7 @@ $columns = $block->getColumns(); </ol> <?php else: ?> <div class="message info empty"> - <span><?php /* @escapeNotVerified */ echo __('This Wish List has no Items');?></span> + <span><?php echo $block->escapeHtml(__('This Wish List has no Items'));?></span> </div> <?php endif; ?> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml index a040c2c8ca7..151834c92c6 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/messages/addProductSuccessMessage.phtml @@ -7,4 +7,5 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> -<?php /* @escapeNotVerified */ echo __('%1 has been added to your Wish List.', $block->escapeHtml($block->getData('product_name'))) ?> <?php /* @escapeNotVerified */ echo __('Click <a href="%1">here</a> to continue shopping.', $block->escapeUrl($block->getData('referer'))); +<?php +echo $block->escapeHtml(__('%1 has been added to your Wish List.', $block->getData('product_name'))) ?> <?php echo $block->escapeHtml(__('Click <a href="%1">here</a> to continue shopping.', $block->getData('referer')), ['a']); diff --git a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml index 8f1b5b3898d..e608837ecc3 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/options_list.phtml @@ -12,9 +12,9 @@ <?php $options = $block->getOptionList(); ?> <?php if ($options): ?> <div class="tooltip wrapper product-item-tooltip"> - <span class="action details tooltip toggle"><?php /* @escapeNotVerified */ echo __('See Details') ?></span> + <span class="action details tooltip toggle"><?php echo $block->escapeHtml(__('See Details')) ?></span> <div class="tooltip content"> - <strong class="subtitle"><?php /* @escapeNotVerified */ echo __('Options Details'); ?></strong> + <strong class="subtitle"><?php echo $block->escapeHtml(__('Options Details')); ?></strong> <dl> <?php foreach ($options as $option): ?> <dt class="label"><?php echo $block->escapeHtml($option['label']) ?></dt> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml index 13685949a29..1b24506993c 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/email.phtml @@ -10,7 +10,7 @@ ?> <?php if ($block->getLink()): ?> <p style="font-size:12px; line-height:16px; margin:0 0 16px;"> - <?php echo __("RSS link to %1's wishlist", $block->escapeHtml($this->helper('Magento\Wishlist\Helper\Data')->getCustomerName())) ?> + <?php echo $block->escapeHtml(__("RSS link to %1's wishlist", $this->helper('Magento\Wishlist\Helper\Data')->getCustomerName())) ?> <br /> <a href="<?php echo $block->escapeUrl($block->getLink()); ?>"><?php echo $block->escapeUrl($block->getLink()); ?></a> </p> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml index 1e297c4673d..056d82419fc 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/rss/wishlist.phtml @@ -10,6 +10,6 @@ ?> <?php if ($block->isRssAllowed() && $block->getLink() && $this->helper('Magento\Wishlist\Helper\Data')->getWishlist()->getItemsCount()): ?> <a href="<?php echo $block->escapeUrl($block->getLink()); ?>" class="action rss wishlist"> - <span><?php /* @escapeNotVerified */ echo __('RSS Feed') ?></span> + <span><?php echo $block->escapeHtml(__('RSS Feed')) ?></span> </a> <?php endif; ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml index 201a5ef3722..0dbee19983a 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/shared.phtml @@ -13,12 +13,12 @@ <form class="form shared wishlist" action="<?php echo $block->escapeUrl($block->getUrl('wishlist/index/update')) ?>" method="post"> <div class="wishlist table-wrapper"> <table class="table data wishlist" id="wishlist-table"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Wish List'); ?></caption> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Wish List')); ?></caption> <thead> <tr> - <th class="col product" scope="col"><?php /* @escapeNotVerified */ echo __('Product') ?></th> - <th class="col comment" scope="col"><?php /* @escapeNotVerified */ echo __('Comment') ?></th> - <th class="col actions" scope="col"><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></th> + <th class="col product" scope="col"><?php echo $block->escapeHtml(__('Product')) ?></th> + <th class="col comment" scope="col"><?php echo $block->escapeHtml(__('Comment')) ?></th> + <th class="col actions" scope="col"><?php echo $block->escapeHtml(__('Add to Cart')) ?></th> </tr> </thead> <tbody> @@ -28,7 +28,7 @@ $isVisibleProduct = $product->isVisibleInSiteVisibility(); ?> <tr> - <td data-th="<?php echo $block->escapeHtml(__('Product')) ?>" class="col product"> + <td data-th="<?php echo $block->escapeHtmlAttr(__('Product')) ?>" class="col product"> <a class="product photo" href="<?php echo $block->escapeUrl($block->getProductUrl($item)) ?>" title="<?php echo $block->escapeHtmlAttr($product->getName()) ?>"> <?php echo $block->getImage($product, 'customer_shared_wishlist')->toHtml(); ?> </a> @@ -47,20 +47,20 @@ ?> <?php echo $block->getDetailsHtml($item) ?> </td> - <td data-th="<?php echo $block->escapeHtml(__('Comment')) ?>" class="col comment"><?php /* @noEscape */ echo $block->getEscapedDescription($item) ?></td> - <td data-th="<?php echo $block->escapeHtml(__('Add to Cart')) ?>" class="col actions" data-role="add-to-links"> + <td data-th="<?php echo $block->escapeHtmlAttr(__('Comment')) ?>" class="col comment"><?php /* @noEscape */ echo $block->getEscapedDescription($item) ?></td> + <td data-th="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>" class="col actions" data-role="add-to-links"> <?php if ($product->isSaleable()): ?> <?php if ($isVisibleProduct): ?> <button type="button" - title="<?php /* @escapeNotVerified */ echo __('Add to Cart') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Add to Cart')) ?>" data-post='<?php /* @noEscape */ echo $block->getSharedItemAddToCartUrl($item); ?>' class="action tocart"> - <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> + <span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span> </button> <?php endif ?> <?php endif; ?> <a href="#" data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($item); ?>' onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist"> - <span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span> + <span><?php echo $block->escapeHtml(__('Add to Wish List')) ?></span> </a> </td> </tr> @@ -73,20 +73,20 @@ <?php if ($block->isSaleable()):?> <div class="primary"> <button type="button" - title="<?php /* @escapeNotVerified */ echo __('Add All to Cart') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Add All to Cart')) ?>" data-post='<?php echo $block->escapeUrl($block->getSharedAddAllToCartUrl()); ?>' class="action tocart primary"> - <span><?php /* @escapeNotVerified */ echo __('Add All to Cart') ?></span> + <span><?php echo $block->escapeHtml(__('Add All to Cart')) ?></span> </button> </div> <?php endif;?> <div class="secondary"> <a href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>" class="action back"> - <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> + <span><?php echo $block->escapeHtml(__('Back')) ?></span> </a> </div> </div> </form> <?php else: ?> - <div class="message info empty"><div><?php /* @escapeNotVerified */ echo __('Wish List is empty now.') ?></div></div> + <div class="message info empty"><div><?php echo $block->escapeHtml(__('Wish List is empty now.')) ?></div></div> <?php endif ?> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml index a21811b384f..aa7c37695d9 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sharing.phtml @@ -12,29 +12,29 @@ action="<?php echo $block->escapeUrl($block->getSendUrl()) ?>" id="form-validate" method="post" - data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>" + data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')) ?>" data-mage-init='{"validation":{}}'> <fieldset class="fieldset"> <?php echo $block->getBlockHtml('formkey')?> - <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Sharing Information') ?></span></legend><br /> + <legend class="legend"><span><?php echo $block->escapeHtml(__('Sharing Information')) ?></span></legend><br /> <div class="field emails required"> - <label class="label" for="email_address"><span><?php /* @escapeNotVerified */ echo __('Email addresses, separated by commas') ?></span></label> + <label class="label" for="email_address"><span><?php echo $block->escapeHtml(__('Email addresses, separated by commas')) ?></span></label> <div class="control"> <textarea name="emails" cols="60" rows="5" id="email_address" data-validate="{required:true,'validate-emails':true}"><?php /* @noEscape */ echo $block->getEnteredData('emails') ?></textarea> </div> </div> <div class="field text"> - <label class="label" for="message"><span><?php /* @escapeNotVerified */ echo __('Message') ?></span></label> + <label class="label" for="message"><span><?php echo $block->escapeHtml(__('Message')) ?></span></label> <div class="control"> <textarea id="message" name="message" cols="60" rows="5"><?php /* @noEscape */ echo $block->getEnteredData('message') ?></textarea> </div> </div> <?php if ($this->helper('Magento\Wishlist\Helper\Rss')->isRssAllow()): ?> <div class="field choice rss"> - <input type="checkbox" name="rss_url" id="rss_url" value="1" title="<?php /* @escapeNotVerified */ echo __('Check here to link an RSS feed to your Wish List.') ?>" class="checkbox"> + <input type="checkbox" name="rss_url" id="rss_url" value="1" title="<?php echo $block->escapeHtmlAttr(__('Check here to link an RSS feed to your Wish List.')) ?>" class="checkbox"> <label class="label" for="rss_url"> <span> - <?php /* @escapeNotVerified */ echo __('Check here to link an RSS feed to your Wish List.') ?> + <?php echo $block->escapeHtml(__('Check here to link an RSS feed to your Wish List.')) ?> </span> </label> </div> @@ -42,12 +42,12 @@ </fieldset> <div class="actions-toolbar"> <div class="primary"> - <button type="submit" title="<?php /* @escapeNotVerified */ echo __('Share Wish List') ?>" class="action submit primary"> - <span><?php /* @escapeNotVerified */ echo __('Share Wish List') ?></span> + <button type="submit" title="<?php echo $block->escapeHtmlAttr(__('Share Wish List')) ?>" class="action submit primary"> + <span><?php echo $block->escapeHtml(__('Share Wish List')) ?></span> </button> </div> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"><span><?php /* @escapeNotVerified */ echo __('Back')?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()); ?>"><span><?php echo $block->escapeHtml(__('Back'))?></span></a> </div> </div> </form> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml index 28e339162d5..1f716f603f3 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/sidebar.phtml @@ -20,7 +20,7 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <!-- /ko --> </div> <div class="block-content"> - <strong class="subtitle"><?php /* @escapeNotVerified */ echo __('Last Added Items') ?></strong> + <strong class="subtitle"><?php echo $block->escapeHtml(__('Last Added Items')) ?></strong> <!-- ko if: wishlist().counter --> <ol class="product-items no-display" id="wishlist-sidebar" data-bind="foreach: wishlist().items, css: {'no-display': null}"> <li class="product-item"> @@ -39,18 +39,18 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <!-- ko if: product_is_saleable_and_visible --> <div class="actions-primary"> <!-- ko if: product_has_required_options --> - <a href="#" data-bind="attr: {'data-post': add_to_cart_params}" class="action tocart primary"><span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span></a> + <a href="#" data-bind="attr: {'data-post': add_to_cart_params}" class="action tocart primary"><span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span></a> <!-- /ko --> <!-- ko ifnot: product_has_required_options --> - <button type="button" class="action tocart primary" data-bind="attr: {'data-post': add_to_cart_params}"><span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span></button> + <button type="button" class="action tocart primary" data-bind="attr: {'data-post': add_to_cart_params}"><span><?php echo $block->escapeHtml(__('Add to Cart')) ?></span></button> <!-- /ko --> </div> <!-- /ko --> <div class="actions-secondary"> <a href="#" data-bind="attr: {'data-post': delete_item_params}" - title="<?php /* @escapeNotVerified */ echo __('Remove This Item') ?>" + title="<?php echo $block->escapeHtmlAttr(__('Remove This Item')) ?>" class="btn-remove action delete"> - <span><?php /* @escapeNotVerified */ echo __('Remove This Item') ?></span> + <span><?php echo $block->escapeHtml(__('Remove This Item')) ?></span> </a> </div> </div> @@ -62,12 +62,12 @@ $wishlistHelper = $this->helper('Magento\Wishlist\Helper\Data'); <div class="primary"> <a class="action details" href="<?php echo $block->escapeUrl($this->helper('Magento\Wishlist\Helper\Data')->getListUrl()) ?>" - title="<?php /* @escapeNotVerified */ echo __('Go to Wish List') ?>"><span><?php /* @escapeNotVerified */ echo __('Go to Wish List') ?></span></a> + title="<?php echo $block->escapeHtmlAttr(__('Go to Wish List')) ?>"><span><?php echo $block->escapeHtml(__('Go to Wish List')) ?></span></a> </div> </div> <!-- /ko --> <!-- ko ifnot: wishlist().counter --> - <div class="empty"><?php /* @escapeNotVerified */ echo __('You have no items in your wish list.') ?></div> + <div class="empty"><?php echo $block->escapeHtml(__('You have no items in your wish list.')) ?></div> <!-- /ko --> </div> </div> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml index 748e1e4386c..ec595385074 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/view.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/view.phtml @@ -23,7 +23,7 @@ <?php $block->getChildBlock('items')->setItems($block->getWishlistItems()); ?> <?php echo $block->getChildHtml('items');?> <?php else: ?> - <div class="message info empty"><span><?php /* @escapeNotVerified */ echo __('You have no items in your wish list.') ?></span></div> + <div class="message info empty"><span><?php echo $block->escapeHtml(__('You have no items in your wish list.')) ?></span></div> <?php endif ?> <?php echo $block->getChildHtml('bottom'); ?> <div class="actions-toolbar"> @@ -32,7 +32,7 @@ </div> <div class="secondary"> <a href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>" class="action back"> - <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> + <span><?php echo $block->escapeHtml(__('Back')) ?></span> </a> </div> </div> -- GitLab From 31a22829b7102daccbd2221df1fff1999f6cf99c Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Tue, 23 Aug 2016 21:43:21 -0500 Subject: [PATCH 641/838] MAGETWO-57232: Eliminate @escapeNotVerified in Wishlist Module - updated blocks where page title is set --- app/code/Magento/Wishlist/Block/Customer/Sharing.php | 2 +- app/code/Magento/Wishlist/Block/Customer/Wishlist.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Sharing.php b/app/code/Magento/Wishlist/Block/Customer/Sharing.php index d447bd7014f..ddf48f1d50a 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Sharing.php +++ b/app/code/Magento/Wishlist/Block/Customer/Sharing.php @@ -56,7 +56,7 @@ class Sharing extends \Magento\Framework\View\Element\Template */ protected function _prepareLayout() { - $this->pageConfig->getTitle()->set(__('Wish List Sharing')); + $this->pageConfig->getTitle()->set($this->escapeHtml(__('Wish List Sharing'))); } /** diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist.php index d37fe5cebeb..4cf3ccd522e 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist.php @@ -79,7 +79,7 @@ class Wishlist extends \Magento\Wishlist\Block\AbstractBlock protected function _prepareLayout() { parent::_prepareLayout(); - $this->pageConfig->getTitle()->set(__('My Wish List')); + $this->pageConfig->getTitle()->set($this->escapeHtml(__('My Wish List'))); } /** -- GitLab From bf19394aabe2d1437ce8ac48a8341c9ebaa4df97 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 24 Aug 2016 08:56:43 -0500 Subject: [PATCH 642/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 110 +++++++++++---------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index c082fff7f53..ba3b93f8668 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -22,30 +22,16 @@ class Escaper * @param array $allowedTags * @return string|array */ - public function escapeHtml($data, $allowedTags = null) + public function escapeHtml($data, $allowedTags = []) { if (is_array($data)) { $result = []; foreach ($data as $item) { - $result[] = $this->escapeHtml($item); + $result[] = $this->escapeHtml($item, $allowedTags); } } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { - $result = $this->filterHtmlTagsAndAttributes($data, $allowedTags); - /* - $allowed = implode('|', $allowedTags); - $result = preg_replace( - '/<([\/\s\r\n]*)(' . $allowed . '[^>]*)([\/\s\r\n]*)>/si', - '##$1$2$3##', - $data - ); - $result = htmlspecialchars($result, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); - $result = preg_replace( - '/##([\/\s\r\n]*)(' . $allowed . '[^##]*)([\/\s\r\n]*)##/si', - '<$1$2$3>', - $result - ); - */ + $result = $this->escapeHtmlTagsAndAttributes($data, $allowedTags); } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } @@ -56,54 +42,76 @@ class Escaper } /** - * Removes not allowed HTML tags and attributes from string + * Escape not allowed HTML entities * * @param string $string * @param string[] $allowedTags * @return string */ - private function filterHtmlTagsAndAttributes($string, $allowedTags) + private function escapeHtmlTagsAndAttributes($string, $allowedTags) { - $wrapperElementId = uniqid(); + $allowedAttributes = ['id', 'class', 'href']; + + $allowedTags = implode('|', $allowedTags); + $allowedAttributes = implode('|', $allowedAttributes); + + $attributeReplacements = []; + + $string = preg_replace_callback( + '/(' . $allowedAttributes . ')="(.*?)"/si', + function ($matches) use (&$attributeReplacements) { + $result = $matches[1] . '=-=quote=--=attribute-value-' . count($attributeReplacements) . '=--=quote=-'; + $attributeReplacements[] = [ + 'name' => $matches[1], + 'value' => $matches[2] + ]; + return $result; + }, + $string + ); - $dom = new \DOMDocument(); - $dom->loadHTML('<span id="' . $wrapperElementId . '">' . $string . '</span>'); - $xpath = new \DOMXPath($dom); + $string = preg_replace( + '/<([\/\s\r\n]*)(' . $allowedTags . ')([^>]*)([\/\s\r\n]*)>/si', + '##$1$2$3$4##', + $string + ); + $string = $this->escapeHtml($string); + $string = preg_replace( + '/##([\/\s\r\n]*)(' . $allowedTags . ')([^##]*)([\/\s\r\n]*)##/si', + '<$1$2$3$4>', + $string + ); - $nodes = $xpath->query('//node()[text() and name() != \'html\' and name() != \'body\' and name() != \'' - . implode('\' and name() != \'', $allowedTags) . '\']'); - foreach ($nodes as $node) { - $node->parentNode->removeChild($node); - } + $attributeReplacements = $this->escapeAttributeValues($attributeReplacements); - $nodes = $xpath->query('//@*[name() != \'' . implode('\' and name() != \'', ['id', 'class', 'href']) . '\']'); - foreach ($nodes as $node) { - $node->parentNode->removeAttribute($node->nodeName); - } + $string = preg_replace_callback( + '/-=quote=--=attribute-value-(\d)=--=quote=-/si', + function($matches) use (&$attributeReplacements) { + return '"' . $attributeReplacements[$matches[1]]['value'] . '"'; + }, + $string + ); - $nodes = $xpath->query('//text()'); - foreach ($nodes as $node) { - $node->textContent = $this->escapeHtml($node->textContent); - } + return $string; + } - $nodes = $xpath->query('//@*'); - foreach ($nodes as $node) { - $value = $node->parentNode->getAttribute($node->nodeName); - if ($node->nodeName == 'href') { - $value = $this->escapeUrl($value); + /** + * Escape attribute values using escapeHtmlAttr and escapeUrl depending on the attribute. $attributes has the + * following structure [['name' => 'id', 'value' => 'identifier'], ['name' => 'href', 'value' => 'http://abc.com/']] + * + * @param array $attributes + * @return array + */ + private function escapeAttributeValues($attributes) + { + foreach ($attributes as $key => $attribute) { + if ($attribute['name'] == 'href') { + $attributes[$key]['value'] = $this->escapeHtml($attribute['value']); } else { - $value = $this->escapeHtmlAttr($value); + $attributes[$key]['value'] = $this->escapeHtmlAttr($attribute['value']); } - $node->parentNode->setAttribute($node->nodeName, $value); } - - $result = mb_convert_encoding( - $dom->saveHTML($dom->getElementById($wrapperElementId)), - 'UTF-8', - 'HTML-ENTITIES' - ); - - return substr($result, 25, strlen($result)-32); + return $attributes; } /** -- GitLab From 693c6b2bb6e7be26082d7bef908e220b455abdb3 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Wed, 24 Aug 2016 09:10:41 -0500 Subject: [PATCH 643/838] MAGETWO-57232: Eliminate @escapeNotVerified in Wishlist Module - reverted changes in blocks --- app/code/Magento/Wishlist/Block/Customer/Sharing.php | 2 +- app/code/Magento/Wishlist/Block/Customer/Wishlist.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/Customer/Sharing.php b/app/code/Magento/Wishlist/Block/Customer/Sharing.php index ddf48f1d50a..d447bd7014f 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Sharing.php +++ b/app/code/Magento/Wishlist/Block/Customer/Sharing.php @@ -56,7 +56,7 @@ class Sharing extends \Magento\Framework\View\Element\Template */ protected function _prepareLayout() { - $this->pageConfig->getTitle()->set($this->escapeHtml(__('Wish List Sharing'))); + $this->pageConfig->getTitle()->set(__('Wish List Sharing')); } /** diff --git a/app/code/Magento/Wishlist/Block/Customer/Wishlist.php b/app/code/Magento/Wishlist/Block/Customer/Wishlist.php index 4cf3ccd522e..d37fe5cebeb 100644 --- a/app/code/Magento/Wishlist/Block/Customer/Wishlist.php +++ b/app/code/Magento/Wishlist/Block/Customer/Wishlist.php @@ -79,7 +79,7 @@ class Wishlist extends \Magento\Wishlist\Block\AbstractBlock protected function _prepareLayout() { parent::_prepareLayout(); - $this->pageConfig->getTitle()->set($this->escapeHtml(__('My Wish List'))); + $this->pageConfig->getTitle()->set(__('My Wish List')); } /** -- GitLab From 877973c70ee45513ef8ea7294d62f45ca56a919d Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 24 Aug 2016 09:37:36 -0500 Subject: [PATCH 644/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 2 +- .../Magento/Framework/Test/Unit/EscaperTest.php | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index ba3b93f8668..b10874252a8 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -58,7 +58,7 @@ class Escaper $attributeReplacements = []; $string = preg_replace_callback( - '/(' . $allowedAttributes . ')="(.*?)"/si', + '/(' . $allowedAttributes . ')=[\'"](.*?)[\'"]/si', function ($matches) use (&$attributeReplacements) { $result = $matches[1] . '=-=quote=--=attribute-value-' . count($attributeReplacements) . '=--=quote=-'; $attributeReplacements[] = [ diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 044e9c8c0fe..c3581df8121 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -69,15 +69,25 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'allowedTags' => ['span', 'b'], ], 'string data with allowed tags with attributes 2' => [ + 'data' => 'Only <span id=\'sku_max_allowed\'><b>2</b></span> in stock', + 'expected' => 'Only <span id="sku_max_allowed"><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + 'string data with allowed tags with attributes 3' => [ 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', 'allowedTags' => ['a'], ], 'string data with allowed tags with attributes and not allowed tags' => [ - 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<two>three</two></a> or <a href="%2"><span id="action">create an account</span></a>', - 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in<two>three</two></a> or <a href="%2"><span id="action">create an account</span></a>', + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', 'allowedTags' => ['a'], ], + 'string data with allowed tags with attributes and not allowed tags 2' => [ + 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a class="some-class" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', + 'expected' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a class="some-class" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', + 'allowedTags' => ['a', 'span'], + ], ]; } -- GitLab From 55a4d4770381ef01214f641be6a909745b677843 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 24 Aug 2016 09:43:08 -0500 Subject: [PATCH 645/838] MAGETWO-57233: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module - Static test problem --- .../view/type/bundle/option/checkbox.phtml | 2 +- .../Utility/XssOutputValidator.php | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/checkbox.phtml b/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/checkbox.phtml index 44cc1ac97e6..96db376bc22 100644 --- a/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/checkbox.phtml +++ b/app/code/Magento/Bundle/view/frontend/templates/catalog/product/view/type/bundle/option/checkbox.phtml @@ -29,7 +29,7 @@ <input class="bundle-option-<?php /* @escapeNotVerified */ echo $_option->getId() ?> checkbox product bundle option change-container-classname" id="bundle-option-<?php /* @escapeNotVerified */ echo $_option->getId() ?>-<?php /* @escapeNotVerified */ echo $_selection->getSelectionId() ?>" type="checkbox" - <?php if ($_option->getRequired()) echo 'data-validate="{\'validate-one-required-by-name\':\'input[name^="bundle_option[' . $_option->getId() . ']"]:checked\'}"'?> + <?php if ($_option->getRequired()) /* @escapeNotVerified */ echo 'data-validate="{\'validate-one-required-by-name\':\'input[name^="bundle_option[' . $_option->getId() . ']"]:checked\'}"'?> name="bundle_option[<?php /* @escapeNotVerified */ echo $_option->getId() ?>][<?php /* @escapeNotVerified */ echo $_selection->getId() ?>]" data-selector="bundle_option[<?php /* @escapeNotVerified */ echo $_option->getId() ?>][<?php /* @escapeNotVerified */ echo $_selection->getId() ?>]" <?php if ($block->isSelected($_selection)) echo ' checked="checked"' ?> diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php index 1e0d684c124..5deda15ed7d 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php +++ b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php @@ -309,7 +309,18 @@ class XssOutputValidator $phpBlock ); - $this->addQuoteOriginsReplacements($phpBlockQuoteReplaced); + $this->addQuoteOriginsReplacements( + $phpBlockQuoteReplaced, + [ + '/([^\\\\])([\'])(.*?)([^\\\\])([\'])/sim' + ] + ); + $this->addQuoteOriginsReplacements( + $phpBlockQuoteReplaced, + [ + '/([^\\\\])(["])(.*?)([^\\\\])(["])/sim', + ] + ); $origins[] = $phpBlock; $replacements[] = str_replace( @@ -354,15 +365,11 @@ class XssOutputValidator * Add replacements for expressions in single and double quotes * * @param string $phpBlock + * @param string[] $patterns * @return void */ - private function addQuoteOriginsReplacements($phpBlock) + private function addQuoteOriginsReplacements($phpBlock, $patterns) { - $patterns = [ - '/([^\\\\])(["])(.*?)([^\\\\])(["])/sim', - '/([^\\\\])([\'])(.*?)([^\\\\])([\'])/sim' - ]; - foreach ($patterns as $pattern) { if (preg_match_all($pattern, $phpBlock, $quoteMatches, PREG_SET_ORDER)) { foreach ($quoteMatches as $quoteMatch) { -- GitLab From 97f814fc865b1ab08ac21334e6a0816c7e167e1a Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 24 Aug 2016 09:58:57 -0500 Subject: [PATCH 646/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b10874252a8..14cab9eefe4 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -15,6 +15,11 @@ class Escaper */ private $escaper; + /** + * @var string[] + */ + private $allowedAttributes = ['id', 'class', 'href', 'target']; + /** * Escape HTML entities * @@ -50,10 +55,8 @@ class Escaper */ private function escapeHtmlTagsAndAttributes($string, $allowedTags) { - $allowedAttributes = ['id', 'class', 'href']; - $allowedTags = implode('|', $allowedTags); - $allowedAttributes = implode('|', $allowedAttributes); + $allowedAttributes = implode('|', $this->allowedAttributes); $attributeReplacements = []; -- GitLab From ba9176c191927f061d0a76777e236baa08230a5b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 24 Aug 2016 10:51:20 -0500 Subject: [PATCH 647/838] MAGETWO-57233: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module - Static test problem --- .../Magento/TestFramework/Utility/XssOutputValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php index 5deda15ed7d..48acb58019a 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php +++ b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php @@ -365,10 +365,10 @@ class XssOutputValidator * Add replacements for expressions in single and double quotes * * @param string $phpBlock - * @param string[] $patterns + * @param array $patterns * @return void */ - private function addQuoteOriginsReplacements($phpBlock, $patterns) + private function addQuoteOriginsReplacements($phpBlock, array $patterns) { foreach ($patterns as $pattern) { if (preg_match_all($pattern, $phpBlock, $quoteMatches, PREG_SET_ORDER)) { -- GitLab From 29333a41b1c96097c113ffa873a995b18b8f28b5 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 24 Aug 2016 11:21:47 -0500 Subject: [PATCH 648/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../Customer/view/frontend/templates/form/edit.phtml | 6 +++--- .../testsuite/Magento/Customer/Block/Widget/TaxvatTest.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 0dddf76d722..716378f4fc1 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -122,9 +122,9 @@ { "[data-role=change-email], [data-role=change-password]": { "changeEmailPassword": { - "titleChangeEmail": "<?php echo $block->escapeJs(__('Change Email')) ?>", - "titleChangePassword": "<?php echo $block->escapeJs(__('Change Password')) ?>", - "titleChangeEmailAndPassword": "<?php echo $block->escapeJs(__('Change Email and Password')) ?>" + "titleChangeEmail": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Email'))) ?>", + "titleChangePassword": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Password'))) ?>", + "titleChangeEmailAndPassword": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Email and Password'))) ?>" } } } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/TaxvatTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/TaxvatTest.php index 33ecb2532e5..f8d0df661d3 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/TaxvatTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Widget/TaxvatTest.php @@ -22,7 +22,7 @@ class TaxvatTest extends \PHPUnit_Framework_TestCase \Magento\Customer\Block\Widget\Taxvat::class ); - $this->assertContains('title="Tax/VAT number"', $block->toHtml()); + $this->assertContains('title="Tax/VAT number"', $block->toHtml()); $this->assertNotContains('required', $block->toHtml()); } @@ -44,7 +44,7 @@ class TaxvatTest extends \PHPUnit_Framework_TestCase \Magento\Customer\Block\Widget\Taxvat::class ); - $this->assertContains('title="Tax/VAT number"', $block->toHtml()); + $this->assertContains('title="Tax/VAT number"', $block->toHtml()); $this->assertContains('required', $block->toHtml()); } -- GitLab From f7be9716cfa9995599fb5fdaca49a0c7e6000053 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Wed, 24 Aug 2016 11:17:06 -0500 Subject: [PATCH 649/838] MAGETWO-57235: Eliminate @escapeNotVerified in Newsletter Module - updated templates --- .../view/adminhtml/templates/preview/iframeswitcher.phtml | 3 ++- .../view/adminhtml/templates/preview/store.phtml | 2 +- .../view/adminhtml/templates/queue/preview.phtml | 4 +++- .../view/adminhtml/templates/subscriber/list.phtml | 2 +- .../view/adminhtml/templates/template/edit.phtml | 8 ++++---- .../view/adminhtml/templates/template/preview.phtml | 4 +++- .../Newsletter/view/frontend/templates/subscribe.phtml | 8 ++++---- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml index aa5679047a5..c8674986cbe 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/iframeswitcher.phtml @@ -6,6 +6,7 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Backend\Block\Page $block */ ?> <div id="preview" class="cms-revision-preview"> <div class="toolbar"> @@ -15,7 +16,7 @@ </div> <?php endif;?> </div> - <iframe name="preview_iframe" id="preview_iframe" frameborder="0" title="<?php /* @escapeNotVerified */ echo __('Preview') ?>" width="100%"></iframe> + <iframe name="preview_iframe" id="preview_iframe" frameborder="0" title="<?php echo $block->escapeHtmlAttr(__('Preview')) ?>" width="100%"></iframe> <?php echo $block->getChildHtml('preview_form'); ?> </div> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml index 7383a8ece33..9574092d4e0 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/preview/store.phtml @@ -10,7 +10,7 @@ <?php if ($websites = $block->getWebsites()): ?> <div class="field field-store-switcher"> - <label class="label" for="store_switcher"><?php /* @escapeNotVerified */ echo __('Choose Store View:') ?></label> + <label class="label" for="store_switcher"><?php echo $block->escapeHtml(__('Choose Store View:')) ?></label> <div class="control"> <select id="store_switcher" diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/queue/preview.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/queue/preview.phtml index 3f94b6c43de..7dc23b28919 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/queue/preview.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/queue/preview.phtml @@ -3,12 +3,14 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** @var \Magento\Framework\View\Element\Template $block */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title><?php /* @escapeNotVerified */ echo __('Newsletter Message Preview'); ?></title> + <title><?php echo $block->escapeHtml(__('Newsletter Message Preview')); ?></title> </head> <body> <?php echo $block->getChildHtml('content') ?> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml index c4092625f20..82c1a9a3492 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/subscriber/list.phtml @@ -17,7 +17,7 @@ <option value="<?php echo $block->escapeHtmlAttr($_queue['value']) ?>"><?php echo $block->escapeHtml($_queue['label']) ?> #<?php echo $block->escapeHtml($_queue['value']) ?></option> <?php endforeach; ?> </select> - <button type="button" class="scalable" onclick="subscriberController.addToQueue();"><span><span><span><?php /* @escapeNotVerified */ echo __('Add to Queue'); ?></span></span></span></button> + <button type="button" class="scalable" onclick="subscriberController.addToQueue();"><span><span><span><?php echo $block->escapeHtml(__('Add to Queue')); ?></span></span></span></button> </div> <?php endif ?> <script> diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml index 61bfd057d45..ea3b7fbb5a9 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/edit.phtml @@ -87,7 +87,7 @@ require([ var self = this; confirm({ - content: "<?php /* @escapeNotVerified */ echo __('Are you sure that you want to strip all tags?') ?>", + content: "<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure that you want to strip all tags?'))) ?>", actions: { confirm: function(){ if(self.isEditor()) { @@ -141,8 +141,8 @@ require([ if($F('code').blank() || $F('code')==templateControl.templateName) { prompt({ - content: '<?php /* @escapeNotVerified */ echo __('Please enter a new template name.') ?>', - value: templateControl.templateName + '<?php /* @escapeNotVerified */ echo __(' Copy') ?>', + content: '<?php echo $block->escapeJs($block->escapeHtml(__('Please enter a new template name.'))) ?>', + value: templateControl.templateName + '<?php echo $block->escapeJs(__(' Copy')) ?>', actions: { confirm: function(value) { $('code').value = value; @@ -200,7 +200,7 @@ require([ deleteTemplate: function() { confirm({ - content: "<?php /* @escapeNotVerified */ echo __('Are you sure you want to delete this template?') ?>", + content: "<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure you want to delete this template?'))) ?>", actions: { confirm: function() { window.location.href = '<?php echo $block->escapeUrl($block->getDeleteUrl()) ?>'; diff --git a/app/code/Magento/Newsletter/view/adminhtml/templates/template/preview.phtml b/app/code/Magento/Newsletter/view/adminhtml/templates/template/preview.phtml index 3f94b6c43de..7dc23b28919 100644 --- a/app/code/Magento/Newsletter/view/adminhtml/templates/template/preview.phtml +++ b/app/code/Magento/Newsletter/view/adminhtml/templates/template/preview.phtml @@ -3,12 +3,14 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** @var \Magento\Framework\View\Element\Template $block */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title><?php /* @escapeNotVerified */ echo __('Newsletter Message Preview'); ?></title> + <title><?php echo $block->escapeHtml(__('Newsletter Message Preview')); ?></title> </head> <body> <?php echo $block->getChildHtml('content') ?> diff --git a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml index 5894c9f8681..fb6989716cd 100644 --- a/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml +++ b/app/code/Magento/Newsletter/view/frontend/templates/subscribe.phtml @@ -19,16 +19,16 @@ data-mage-init='{"validation": {"errorClass": "mage-error"}}' id="newsletter-validate-detail"> <div class="field newsletter"> - <label class="label" for="newsletter"><span><?php /* @escapeNotVerified */ echo __('Sign Up for Our Newsletter:') ?></span></label> + <label class="label" for="newsletter"><span><?php echo $block->escapeHtml(__('Sign Up for Our Newsletter:')) ?></span></label> <div class="control"> <input name="email" type="email" id="newsletter" - placeholder="<?php /* @escapeNotVerified */ echo __('Enter your email address') ?>" + placeholder="<?php echo $block->escapeHtmlAttr(__('Enter your email address')) ?>" data-validate="{required:true, 'validate-email':true}"/> </div> </div> <div class="actions"> - <button class="action subscribe primary" title="<?php /* @escapeNotVerified */ echo __('Subscribe') ?>" type="submit"> - <span><?php /* @escapeNotVerified */ echo __('Subscribe') ?></span> + <button class="action subscribe primary" title="<?php echo $block->escapeHtmlAttr(__('Subscribe')) ?>" type="submit"> + <span><?php echo $block->escapeHtml(__('Subscribe')) ?></span> </button> </div> </form> -- GitLab From f74a9993601b14ba41ee001d14f8114c17c540c0 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Wed, 24 Aug 2016 14:49:27 -0500 Subject: [PATCH 650/838] MAGETWO-57232: Eliminate @escapeNotVerified in Wishlist Module - fixed double-escaping --- .../templates/catalog/product/list/addto/wishlist.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml index 5e743c0af45..d6374b19ed7 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/catalog/product/list/addto/wishlist.phtml @@ -11,7 +11,7 @@ <?php if ($block->getWishlistHelper()->isAllow()): ?> <a href="#" class="action towishlist" - title="<?php echo $block->escapeHtmlAttr($block->escapeHtmlAttr(__('Add to Wish List'))); ?>" + title="<?php echo $block->escapeHtmlAttr(__('Add to Wish List')); ?>" aria-label="<?php echo $block->escapeHtmlAttr(__('Add to Wish List')); ?>" data-post='<?php /* @noEscape */ echo $block->getAddToWishlistParams($block->getProduct()); ?>' data-action="add-to-wishlist" -- GitLab From 845ffccf184f683ab66ca3ef046483075b340f9e Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 24 Aug 2016 15:54:29 -0500 Subject: [PATCH 651/838] MAGETWO-57232: Eliminate @escapeNotVerified in Wishlist Module --- app/code/Magento/Wishlist/Block/AddToWishlist.php | 3 ++- .../Block/Catalog/Product/View/AddTo/Wishlist.php | 2 +- app/code/Magento/Wishlist/Block/Item/Configure.php | 2 +- .../templates/customer/edit/tab/wishlist.phtml | 10 +++++----- .../Wishlist/view/frontend/templates/addto.phtml | 2 ++ 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Wishlist/Block/AddToWishlist.php b/app/code/Magento/Wishlist/Block/AddToWishlist.php index db6dae099fe..67ef95bcbce 100644 --- a/app/code/Magento/Wishlist/Block/AddToWishlist.php +++ b/app/code/Magento/Wishlist/Block/AddToWishlist.php @@ -55,9 +55,10 @@ class AddToWishlist extends \Magento\Framework\View\Element\Template $block = $this->getLayout()->getBlock('category.products.list'); if ($block) { $productCollection = $block->getLoadedProductCollection(); + $productTypes = []; /** @var $product \Magento\Catalog\Model\Product */ foreach ($productCollection as $product) { - $productTypes[] = $product->getTypeId(); + $productTypes[] = $this->escapeHtml($product->getTypeId()); } $this->productTypes = array_unique($productTypes); } diff --git a/app/code/Magento/Wishlist/Block/Catalog/Product/View/AddTo/Wishlist.php b/app/code/Magento/Wishlist/Block/Catalog/Product/View/AddTo/Wishlist.php index 6f2cb307c1a..1a888f1fd0f 100644 --- a/app/code/Magento/Wishlist/Block/Catalog/Product/View/AddTo/Wishlist.php +++ b/app/code/Magento/Wishlist/Block/Catalog/Product/View/AddTo/Wishlist.php @@ -28,7 +28,7 @@ class Wishlist extends \Magento\Catalog\Block\Product\View */ public function getWishlistOptions() { - return ['productType' => $this->getProduct()->getTypeId()]; + return ['productType' => $this->escapeHtml($this->getProduct()->getTypeId())]; } /** diff --git a/app/code/Magento/Wishlist/Block/Item/Configure.php b/app/code/Magento/Wishlist/Block/Item/Configure.php index 5ae59dfe313..71a37d34eb2 100644 --- a/app/code/Magento/Wishlist/Block/Item/Configure.php +++ b/app/code/Magento/Wishlist/Block/Item/Configure.php @@ -52,7 +52,7 @@ class Configure extends \Magento\Framework\View\Element\Template */ public function getWishlistOptions() { - return ['productType' => $this->getProduct()->getTypeId()]; + return ['productType' => $this->escapeHtml($this->getProduct()->getTypeId())]; } /** diff --git a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml index d360c5dfc24..d9fc32e1b13 100644 --- a/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml +++ b/app/code/Magento/Wishlist/view/adminhtml/templates/customer/edit/tab/wishlist.phtml @@ -21,13 +21,13 @@ if (!urlParams) { urlParams = ''; } - var url = <?php echo $block->escapeJs($block->getJsObjectName()) ?>.url + '?ajax=true' + urlParams; + var url = <?php echo $block->escapeJs($block->escapeUrl($block->getJsObjectName())) ?>.url + '?ajax=true' + urlParams; new Ajax.Updater( - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.containerId, + <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.containerId, url, { parameters: {form_key: FORM_KEY}, - onComplete: <?php echo $block->escapeJs($block->getJsObjectName()) ?>.initGrid.bind(<?php echo $block->escapeJs($block->getJsObjectName()) ?>), + onComplete: <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.initGrid.bind(<?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>), evalScripts:true } ); @@ -63,8 +63,8 @@ productConfigure.addListType( 'wishlist', { - urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/configure')) ?>', - urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/update')) ?>' + urlFetch: '<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/configure'))) ?>', + urlConfirm: '<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('customer/wishlist_product_composite_wishlist/update'))) ?>' } ); //--> diff --git a/app/code/Magento/Wishlist/view/frontend/templates/addto.phtml b/app/code/Magento/Wishlist/view/frontend/templates/addto.phtml index 99c505fdc0c..75411a6a71b 100644 --- a/app/code/Magento/Wishlist/view/frontend/templates/addto.phtml +++ b/app/code/Magento/Wishlist/view/frontend/templates/addto.phtml @@ -3,6 +3,8 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** @var \Magento\Wishlist\Block\AddToWishlist $block */ ?> <script type="text/x-magento-init"> { -- GitLab From 4d417cfed2b5c0a6d15864c55923d9a82e345717 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Wed, 24 Aug 2016 15:21:27 -0500 Subject: [PATCH 652/838] MAGETWO-57237: Eliminate @escapeNotVerified in Review Module - updated templates --- .../adminhtml/templates/rating/detailed.phtml | 2 +- .../adminhtml/templates/rating/form.phtml | 3 ++- .../adminhtml/templates/rating/options.phtml | 7 ++--- .../templates/rating/stars/detailed.phtml | 3 ++- .../templates/rating/stars/summary.phtml | 2 +- .../frontend/templates/customer/list.phtml | 26 +++++++++---------- .../frontend/templates/customer/recent.phtml | 6 ++--- .../frontend/templates/customer/view.phtml | 8 +++--- .../view/frontend/templates/detailed.phtml | 4 +-- .../view/frontend/templates/empty.phtml | 4 ++- .../Review/view/frontend/templates/form.phtml | 22 ++++++++-------- .../frontend/templates/helper/summary.phtml | 8 +++--- .../templates/helper/summary_short.phtml | 6 ++--- .../templates/product/view/count.phtml | 4 +-- .../templates/product/view/list.phtml | 6 ++--- .../templates/product/view/other.phtml | 2 +- .../Review/view/frontend/templates/view.phtml | 14 +++++----- 17 files changed, 66 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml index 89073febf02..2c7ca7a61ec 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/detailed.phtml @@ -37,5 +37,5 @@ require([ }); </script> <?php else: ?> - <?php /* @escapeNotVerified */ echo __("Rating isn't Available") ?> + <?php echo $block->escapeHtml(__("Rating isn't Available")) ?> <?php endif; ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/form.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/form.phtml index a46dcad3b7b..019cbec2944 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/form.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/form.phtml @@ -6,10 +6,11 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Review\Block\Adminhtml\Rating\Edit\Tab\Form $block */ ?> <div class="messages"> <div class="message message-notice message-in-rating-edit"> - <div><?php /* @escapeNotVerified */ echo __('Please specify a rating title for a store, or we\'ll just use the default value.'); ?></div> + <div><?php echo $block->escapeHtml(__('Please specify a rating title for a store, or we\'ll just use the default value.')); ?></div> </div> </div> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml index 8fe776fb345..f267d8e9957 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/options.phtml @@ -5,22 +5,23 @@ */ // @codingStandardsIgnoreFile +// @deprecated ?> <div class="entry-edit-head"> - <h4 class="icon-head head-edit-form fieldset-legend"><?php /* @escapeNotVerified */ echo __('Assigned Options') ?></h4> + <h4 class="icon-head head-edit-form fieldset-legend"><?php echo $block->escapeHtml(__('Assigned Options')) ?></h4> </div> <fieldset id="options_form"> <?php if (!$options): ?> <?php for ($_i = 1; $_i <= 5; $_i++): ?> <span class="field-row"> - <label for="option_<?php /* @noEscape */ echo $_i ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <label for="option_<?php /* @noEscape */ echo $_i ?>"><?php echo $block->escapeHtml(__('Option Title:')) ?></label> <input id="option_<?php /* @noEscape */ echo $_i ?>" name="option[<?php /* @noEscape */ echo $_i ?>][code]" value="<?php /* @noEscape */ echo $_i ?>" class="input-text" type="text" /> </span> <?php endfor; ?> <?php elseif ($options->getSize() > 0): ?> <?php foreach ($options->getItems() as $_item): ?> <span class="field-row"> - <label for="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Option Title:') ?></label> + <label for="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>"><?php echo $block->escapeHtml(__('Option Title:')) ?></label> <input id="option_<?php echo $block->escapeHtmlAttr($_item->getId()) ?>" name="option[<?php echo $block->escapeHtmlAttr($_item->getId()) ?>][code]" value="<?php echo $block->escapeHtmlAttr($_item->getCode()) ?>" class="input-text" type="text" /> </span> <?php endforeach; ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml index 86ae33dae3e..930ddcc6cce 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/detailed.phtml @@ -5,6 +5,7 @@ */ // @codingStandardsIgnoreFile +// @deprecated ?> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> <div class="ratings-container"> @@ -20,5 +21,5 @@ <?php endforeach; ?> </div> <?php else: ?> - <?php /* @escapeNotVerified */ echo __("Rating isn't Available") ?> + <?php echo $block->escapeHtml(__("Rating isn't Available")) ?> <?php endif; ?> diff --git a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml index 1badd869907..8c4ea6a02c1 100644 --- a/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml +++ b/app/code/Magento/Review/view/adminhtml/templates/rating/stars/summary.phtml @@ -13,5 +13,5 @@ <div class="rating" style="width:<?php /* @noEscape */ echo ceil($block->getRatingSummary()->getSum() / ($block->getRatingSummary()->getCount())) ?>%;"></div> </div> <?php else: ?> - <?php /* @escapeNotVerified */ echo __("Rating isn't Available") ?> + <?php echo $block->escapeHtml(__("Rating isn't Available")) ?> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index 578f8d19c22..9a17e0ff33f 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -11,13 +11,13 @@ <?php if ($block->getReviews() && count($block->getReviews())): ?> <div class="table-wrapper reviews"> <table class="data table table-reviews" id="my-reviews-table"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Product Reviews') ?></caption> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Product Reviews')) ?></caption> <thead> <tr> - <th scope="col" class="col date"><?php /* @escapeNotVerified */ echo __('Created') ?></th> - <th scope="col" class="col item"><?php /* @escapeNotVerified */ echo __('Product Name') ?></th> - <th scope="col" class="col summary"><?php /* @escapeNotVerified */ echo __('Rating') ?></th> - <th scope="col" class="col description"><?php /* @escapeNotVerified */ echo __('Review') ?></th> + <th scope="col" class="col date"><?php echo $block->escapeHtml(__('Created')) ?></th> + <th scope="col" class="col item"><?php echo $block->escapeHtml(__('Product Name')) ?></th> + <th scope="col" class="col summary"><?php echo $block->escapeHtml(__('Rating')) ?></th> + <th scope="col" class="col description"><?php echo $block->escapeHtml(__('Review')) ?></th> <th scope="col" class="col actions"> </th> </tr> </thead> @@ -33,19 +33,19 @@ <td data-th="<?php echo $block->escapeHtml(__('Rating')) ?>" class="col summary"> <?php if ($_review->getSum()): ?> <div class="rating-summary"> - <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> - <div class="rating-result" title="<?php /* @escapeNotVerified */ echo($_review->getSum() / $_review->getCount()) ?>%"> - <span style="width:<?php /* @escapeNotVerified */ echo($_review->getSum() / $_review->getCount()) ?>%;"><span><?php /* @escapeNotVerified */ echo($_review->getSum() / $_review->getCount()) ?>%</span></span> + <span class="label"><span><?php echo $block->escapeHtml(__('Rating')) ?>:</span></span> + <div class="rating-result" title="<?php echo ((int)$_review->getSum() / (int)$_review->getCount()) ?>%"> + <span style="width:<?php echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%;"><span><?php echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%</span></span> </div> </div> <?php endif; ?> </td> - <td data-th="<?php echo $block->escapeHtml(__('Review')) ?>" class="col description"> + <td data-th="<?php echo $block->escapeHtmlAttr(__('Review')) ?>" class="col description"> <?php echo $this->helper('Magento\Review\Helper\Data')->getDetailHtml($_review->getDetail()) ?> </td> - <td data-th="<?php echo $block->escapeHtml(__('Actions')) ?>" class="col actions"> + <td data-th="<?php echo $block->escapeHtmlAttr(__('Actions')) ?>" class="col actions"> <a href="<?php echo $block->escapeUrl($block->getReviewUrl($_review)) ?>" class="action more"> - <span><?php /* @escapeNotVerified */ echo __('See Details') ?></span> + <span><?php echo $block->escapeHtml(__('See Details')) ?></span> </a> </td> </tr> @@ -59,12 +59,12 @@ </div> <?php endif; ?> <?php else: ?> - <div class="message info empty"><span><?php /* @escapeNotVerified */ echo __('You have submitted no reviews.') ?></span></div> + <div class="message info empty"><span><?php echo $block->escapeHtml(__('You have submitted no reviews.')) ?></span></div> <?php endif; ?> <div class="actions-toolbar"> <div class="secondary"> <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Back') ?></span> + <span><?php echo $block->escapeHtml(__('Back')) ?></span> </a> </div> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml index b232b832b86..1807096b315 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/recent.phtml @@ -11,8 +11,8 @@ <?php if ($block->getReviews() && count($block->getReviews())): ?> <div class="block block-reviews-dashboard"> <div class="block-title"> - <strong><?php /* @escapeNotVerified */ echo __('My Recent Reviews') ?></strong> - <a class="action view" href="<?php echo $block->escapeUrl($block->getAllReviewsUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('View All') ?></span></a> + <strong><?php echo $block->escapeHtml(__('My Recent Reviews')) ?></strong> + <a class="action view" href="<?php echo $block->escapeUrl($block->getAllReviewsUrl()) ?>"><span><?php echo $block->escapeHtml(__('View All')) ?></span></a> </div> <div class="block-content"> <ol class="items"> @@ -22,7 +22,7 @@ <?php if ($_review->getSum()): ?> <?php $rating = $_review->getSum() / $_review->getCount() ?> <div class="rating-summary"> - <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> + <span class="label"><span><?php echo $block->escapeHtml(__('Rating')) ?>:</span></span> <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"><span><?php echo $block->escapeHtml($rating); ?>%</span></span> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml index 9937fce922f..638d53da64e 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/view.phtml @@ -22,7 +22,7 @@ $product = $block->getProductData(); <div class="product-info"> <h2 class="product-name"><?php echo $block->escapeHtml($product->getName()) ?></h2> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> - <span class="rating-average-label"><?php /* @escapeNotVerified */ echo __('Average Customer Rating:') ?></span> + <span class="rating-average-label"><?php echo $block->escapeHtml(__('Average Customer Rating:')) ?></span> <?php echo $block->getReviewsSummaryHtml($product) ?> <?php endif; ?> </div> @@ -31,7 +31,7 @@ $product = $block->getProductData(); <div class="review-details"> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> <div class="title"> - <strong><?php /* @escapeNotVerified */ echo __('Your Review'); ?></strong> + <strong><?php echo $block->escapeHtml(__('Your Review')); ?></strong> </div> <div class="customer-review-rating"> <?php foreach ($block->getRating() as $_rating): ?> @@ -53,13 +53,13 @@ $product = $block->getProductData(); <div class="review-title"><?php echo $block->escapeHtml($block->getReviewData()->getTitle()) ?></div> <div class="review-content"><?php echo nl2br($block->escapeHtml($block->getReviewData()->getDetail())) ?></div> <div class="review-date"> - <?php /* @escapeNotVerified */ echo __('Submitted on %1', '<time class="date">' . $block->dateFormat($block->getReviewData()->getCreatedAt()) . '</time>') ?> + <?php echo $block->escapeHtml(__('Submitted on %1', '<time class="date">' . $block->dateFormat($block->getReviewData()->getCreatedAt()) . '</time>'), ['time']) ?> </div> </div> </div> <div class="actions-toolbar"> <div class="secondary"> - <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Back to My Reviews') ?></span></a> + <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php echo $block->escapeHtml(__('Back to My Reviews')) ?></span></a> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/detailed.phtml b/app/code/Magento/Review/view/frontend/templates/detailed.phtml index 72bd4fcaca3..46d7b34a757 100644 --- a/app/code/Magento/Review/view/frontend/templates/detailed.phtml +++ b/app/code/Magento/Review/view/frontend/templates/detailed.phtml @@ -11,12 +11,12 @@ <?php if (!empty($collection) && $collection->getSize()): ?> <div class="table-wrapper"> <table class="data table ratings review summary"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Ratings Review Summary'); ?></caption> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Ratings Review Summary')); ?></caption> <tbody> <?php foreach ($collection as $_rating): ?> <?php if ($_rating->getSummary()): ?> <tr> - <th class="label" scope="row"><?php echo __($block->escapeHtml($_rating->getRatingCode())) ?></th> + <th class="label" scope="row"><?php echo $block->escapeHtml(__($_rating->getRatingCode())) ?></th> <td class="value"> <div class="rating box"> <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getSummary()) ?>%;"></div> diff --git a/app/code/Magento/Review/view/frontend/templates/empty.phtml b/app/code/Magento/Review/view/frontend/templates/empty.phtml index 7029fe75ca7..9f32021c3d1 100644 --- a/app/code/Magento/Review/view/frontend/templates/empty.phtml +++ b/app/code/Magento/Review/view/frontend/templates/empty.phtml @@ -5,5 +5,7 @@ */ // @codingStandardsIgnoreFile + +/** @var \Magento\Review\Block\Rating\Entity\Detailed $block */ ?> -<p class="no-rating"><a href="#review-form"><?php /* @escapeNotVerified */ echo __('Be the first to review this product') ?></a></p> +<p class="no-rating"><a href="#review-form"><?php echo $block->escapeHtml(__('Be the first to review this product')) ?></a></p> diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index 611416586dd..04e55e0b118 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -9,18 +9,18 @@ /** @var \Magento\Review\Block\Form $block */ ?> <div class="block review-add"> - <div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Write Your Own Review') ?></strong></div> + <div class="block-title"><strong><?php echo $block->escapeHtml(__('Write Your Own Review')) ?></strong></div> <div class="block-content"> <?php if ($block->getAllowWriteReviewFlag()): ?> <form action="<?php echo $block->escapeUrl($block->getAction()) ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'"> <?php echo $block->getBlockHtml('formkey'); ?> <?php echo $block->getChildHtml('form_fields_before')?> - <fieldset class="fieldset review-fieldset" data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields'); ?>"> - <legend class="legend review-legend"><span><?php /* @escapeNotVerified */ echo __("You're reviewing:"); ?></span><strong><?php echo $block->escapeHtml($block->getProductInfo()->getName()) ?></strong></legend><br /> + <fieldset class="fieldset review-fieldset" data-hasrequired="<?php echo $block->escapeHtmlAttr(__('* Required Fields')); ?>"> + <legend class="legend review-legend"><span><?php echo $block->escapeHtml(__("You're reviewing:")); ?></span><strong><?php echo $block->escapeHtml($block->getProductInfo()->getName()) ?></strong></legend><br /> <?php if ($block->getRatings() && $block->getRatings()->getSize()): ?> <span id="input-message-box"></span> <fieldset class="field required review-field-ratings"> - <legend class="label"><span><?php /* @escapeNotVerified */ echo __('Your Rating') ?><span></legend><br/> + <legend class="label"><span><?php echo $block->escapeHtml(__('Your Rating')) ?><span></legend><br/> <div class="control"> <div class="nested" id="product-review-table"> <?php foreach ($block->getRatings() as $_rating): ?> @@ -40,9 +40,9 @@ <label class="rating-<?php echo $block->escapeHtmlAttr($iterator); ?>" for="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>" - title="<?php /* @escapeNotVerified */ echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?>" + title="<?php echo $block->escapeHtmlAttr(__('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star')) ?>" id="<?php echo $block->escapeHtmlAttr($_rating->getRatingCode()) ?>_<?php echo $block->escapeHtmlAttr($_option->getValue()) ?>_label"> - <span><?php /* @escapeNotVerified */ echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?></span> + <span><?php echo $block->escapeHtml(__('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star')) ?></span> </label> <?php $iterator++; ?> <?php endforeach; ?> @@ -55,19 +55,19 @@ </fieldset> <?php endif ?> <div class="field review-field-nickname required"> - <label for="nickname_field" class="label"><span><?php /* @escapeNotVerified */ echo __('Nickname') ?></span></label> + <label for="nickname_field" class="label"><span><?php echo $block->escapeHtml(__('Nickname')) ?></span></label> <div class="control"> <input type="text" name="nickname" id="nickname_field" class="input-text" data-validate="{required:true}" data-bind="value: nickname()" /> </div> </div> <div class="field review-field-summary required"> - <label for="summary_field" class="label"><span><?php /* @escapeNotVerified */ echo __('Summary') ?></span></label> + <label for="summary_field" class="label"><span><?php echo $block->escapeHtml(__('Summary')) ?></span></label> <div class="control"> <input type="text" name="title" id="summary_field" class="input-text" data-validate="{required:true}" data-bind="value: review().title" /> </div> </div> <div class="field review-field-text required"> - <label for="review_field" class="label"><span><?php /* @escapeNotVerified */ echo __('Review') ?></span></label> + <label for="review_field" class="label"><span><?php echo $block->escapeHtml(__('Review')) ?></span></label> <div class="control"> <textarea name="detail" id="review_field" cols="5" rows="3" data-validate="{required:true}" data-bind="value: review().detail"></textarea> </div> @@ -75,7 +75,7 @@ </fieldset> <div class="actions-toolbar review-form-actions"> <div class="primary actions-primary"> - <button type="submit" class="action submit primary"><span><?php /* @escapeNotVerified */ echo __('Submit Review') ?></span></button> + <button type="submit" class="action submit primary"><span><?php echo $block->escapeHtml(__('Submit Review')) ?></span></button> </div> </div> </form> @@ -92,7 +92,7 @@ <?php else: ?> <div class="message info notlogged" id="review-form"> <div> - <?php /* @escapeNotVerified */ echo __('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginLink(), $block->getRegisterUrl()) ?> + <?php echo $block->escapeHtml(__('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginLink(), $block->getRegisterUrl(), ['a'])) ?> </div> </div> <?php endif ?> diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml index cc5d8a0b6ae..eabdb0a3e51 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary.phtml @@ -16,22 +16,22 @@ $urlForm = $block->getReviewsUrl() . '#review-form'; <div class="product-reviews-summary<?php echo !$rating ? ' no-rating' : ''?>" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"> <?php if ($rating):?> <div class="rating-summary"> - <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> + <span class="label"><span><?php echo $block->escapeHtml(__('Rating')) ?>:</span></span> <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"><span><span itemprop="ratingValue"><?php echo $block->escapeHtml($rating); ?></span>% of <span itemprop="bestRating">100</span></span></span> </div> </div> <?php endif;?> <div class="reviews-actions"> - <a class="action view" href="<?php echo $block->escapeUrl($url) ?>"><span itemprop="reviewCount"><?php echo $block->escapeHtml($block->getReviewsCount()) ?></span> <span><?php /* @escapeNotVerified */ echo($block->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> - <a class="action add" href="<?php echo $block->escapeUrl($urlForm) ?>"><?php /* @escapeNotVerified */ echo __('Add Your Review') ?></a> + <a class="action view" href="<?php echo $block->escapeUrl($url) ?>"><span itemprop="reviewCount"><?php echo $block->escapeHtml($block->getReviewsCount()) ?></span> <span><?php echo($block->getReviewsCount() == 1) ? $block->escapeHtml(__('Review')) : $block->escapeHtml(__('Reviews')) ?></span></a> + <a class="action add" href="<?php echo $block->escapeUrl($urlForm) ?>"><?php echo $block->escapeHtml(__('Add Your Review')) ?></a> </div> </div> <?php elseif ($block->getDisplayIfEmpty()): ?> <div class="product-reviews-summary empty"> <div class="reviews-actions"> <a class="action add" href="<?php echo $block->escapeUrl($urlForm); ?>"> - <?php /* @escapeNotVerified */ echo __('Be the first to review this product') ?> + <?php echo $block->escapeHtml(__('Be the first to review this product')) ?> </a> </div> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml index 14650e7b0e0..90ddfda19f2 100644 --- a/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml +++ b/app/code/Magento/Review/view/frontend/templates/helper/summary_short.phtml @@ -16,21 +16,21 @@ $urlForm = $block->getReviewsUrl() . '#review-form'; <div class="product-reviews-summary short<?php echo !$rating ? ' no-rating' : ''?>"> <?php if ($rating):?> <div class="rating-summary"> - <span class="label"><span><?php /* @escapeNotVerified */ echo __('Rating') ?>:</span></span> + <span class="label"><span><?php echo $block->escapeHtml(__('Rating')) ?>:</span></span> <div class="rating-result" title="<?php echo $block->escapeHtmlAttr($rating); ?>%"> <span style="width:<?php echo $block->escapeHtmlAttr($rating); ?>%"><span><?php echo $block->escapeHtml($rating); ?>%</span></span> </div> </div> <?php endif;?> <div class="reviews-actions"> - <a class="action view" href="<?php echo $block->escapeUrl($url) ?>"><?php echo $block->escapeHtml($block->getReviewsCount()) ?> <span><?php /* @escapeNotVerified */ echo($block->getReviewsCount() == 1) ? __('Review') : __('Reviews') ?></span></a> + <a class="action view" href="<?php echo $block->escapeUrl($url) ?>"><?php echo $block->escapeHtml($block->getReviewsCount()) ?> <span><?php echo($block->getReviewsCount() == 1) ? $block->escapeHtml(__('Review')) : $block->escapeHtml(__('Reviews')) ?></span></a> </div> </div> <?php elseif ($block->getDisplayIfEmpty()): ?> <div class="product-reviews-summary short empty"> <div class="reviews-actions"> <a class="action add" href="<?php echo $block->escapeUrl($urlForm); ?>"> - <?php /* @escapeNotVerified */ echo __('Be the first to review this product') ?> + <?php echo $block->escapeHtml(__('Be the first to review this product')) ?> </a> </div> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/count.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/count.phtml index fb7741a5ea2..8b515ca2b7b 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/count.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/count.phtml @@ -5,8 +5,8 @@ */ // @codingStandardsIgnoreFile - +// @deprecated ?> <?php if (!empty($count)):?> - <a href="#customer-reviews" class="nobr"><?php /* @escapeNotVerified */ echo __('%1 Review(s)', $count) ?></a> + <a href="#customer-reviews" class="nobr"><?php echo $block->escapeHtml(__('%1 Review(s)', $count)) ?></a> <?php endif;?> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml index 9eb4fd10fec..262208b169e 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/list.phtml @@ -14,7 +14,7 @@ $format = $block->getDateFormat() ?: \IntlDateFormatter::SHORT; <?php if (count($_items)):?> <div class="block review-list" id="customer-reviews"> <div class="block-title"> - <strong><?php /* @escapeNotVerified */ echo __('Customer Reviews') ?></strong> + <strong><?php echo $block->escapeHtml(__('Customer Reviews')) ?></strong> </div> <div class="block-content"> <div class="toolbar review-toolbar"> @@ -45,11 +45,11 @@ $format = $block->getDateFormat() ?: \IntlDateFormatter::SHORT; </div> <div class="review-details"> <p class="review-author"> - <span class="review-details-label"><?php /* @escapeNotVerified */ echo __('Review by')?></span> + <span class="review-details-label"><?php echo $block->escapeHtml(__('Review by'))?></span> <strong class="review-details-value" itemprop="author"><?php echo $block->escapeHtml($_review->getNickname()) ?></strong> </p> <p class="review-date"> - <span class="review-details-label"><?php /* @escapeNotVerified */ echo __('Posted on') ?></span> + <span class="review-details-label"><?php echo $block->escapeHtml(__('Posted on')) ?></span> <time class="review-details-value" itemprop="datePublished" datetime="<?php echo $block->escapeHtmlAttr($block->formatDate($_review->getCreatedAt(), $format)) ?>"><?php echo $block->escapeHtml($block->formatDate($_review->getCreatedAt(), $format)) ?></time> </p> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml b/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml index 3c8d626b317..fadc72ce7da 100644 --- a/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml +++ b/app/code/Magento/Review/view/frontend/templates/product/view/other.phtml @@ -10,5 +10,5 @@ ?> <?php $_product = $block->getProduct(); ?> <div class="actions"> - <a href="<?php echo $block->escapeUrl($_product->getProductUrl()) ?>" class="action back"><span><?php /* @escapeNotVerified */ echo __('Back to Main Product Info') ?></span></a> + <a href="<?php echo $block->escapeUrl($_product->getProductUrl()) ?>" class="action back"><span><?php echo $block->escapeHtml(__('Back to Main Product Info')) ?></span></a> </div> diff --git a/app/code/Magento/Review/view/frontend/templates/view.phtml b/app/code/Magento/Review/view/frontend/templates/view.phtml index f44d31d63f7..12a28ccf540 100644 --- a/app/code/Magento/Review/view/frontend/templates/view.phtml +++ b/app/code/Magento/Review/view/frontend/templates/view.phtml @@ -11,28 +11,28 @@ <?php if ($block->getProductData()->getId()): ?> <div class="product-review"> <div class="page-title-wrapper"> - <h1><?php /* @escapeNotVerified */ echo __('Review Details') ?></h1> + <h1><?php echo $block->escapeHtml(__('Review Details')) ?></h1> </div> <div class="product-img-box"> <a href="<?php echo $block->escapeUrl($block->getProductData()->getProductUrl()) ?>"> <?php echo $block->getImage($block->getProductData(), 'product_base_image', ['class' => 'product-image'])->toHtml(); ?> </a> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> - <p><?php /* @escapeNotVerified */ echo __('Average Customer Rating') ?>:</p> + <p><?php echo $block->escapeHtml(__('Average Customer Rating')) ?>:</p> <?php echo $block->getReviewsSummaryHtml($block->getProductData()) ?> <?php endif; ?> </div> <div class="details"> <h3 class="product-name"><?php echo $block->escapeHtml($block->getProductData()->getName()) ?></h3> <?php if ($block->getRating() && $block->getRating()->getSize()): ?> - <h4><?php /* @escapeNotVerified */ echo __('Product Rating:') ?></h4> + <h4><?php echo $block->escapeHtml(__('Product Rating:')) ?></h4> <div class="table-wrapper"> <table class="data-table review-summary-table"> - <caption class="table-caption"><?php /* @escapeNotVerified */ echo __('Product Rating'); ?></caption> + <caption class="table-caption"><?php echo $block->escapeHtml(__('Product Rating')); ?></caption> <?php foreach ($block->getRating() as $_rating): ?> <?php if ($_rating->getPercent()): ?> <tr> - <td class="label"><?php echo __($block->escapeHtml($_rating->getRatingCode())) ?></td> + <td class="label"><?php echo $block->escapeHtml(__($_rating->getRatingCode())) ?></td> <td class="value"> <div class="rating-box"> <div class="rating" style="width:<?php /* @noEscape */ echo ceil($_rating->getPercent()) ?>%;"></div> @@ -43,13 +43,13 @@ </table> </div> <?php endif; ?> - <p class="date"><?php /* @escapeNotVerified */ echo __('Product Review (submitted on %1):', $block->dateFormat($block->getReviewData()->getCreatedAt())) ?></p> + <p class="date"><?php echo $block->escapeHtml(__('Product Review (submitted on %1):', $block->dateFormat($block->getReviewData()->getCreatedAt()))) ?></p> <p><?php echo nl2br($block->escapeHtml($block->getReviewData()->getDetail())) ?></p> </div> <div class="actions"> <div class="secondary"> <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"> - <span><?php /* @escapeNotVerified */ echo __('Back to Product Reviews') ?></a></span> + <span><?php echo $block->escapeHtml(__('Back to Product Reviews')) ?></a></span> </a> </div> </div> -- GitLab From 51ac8b636d0e55e09b68a4cb06d60bc5622d1b06 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Wed, 24 Aug 2016 16:56:14 -0500 Subject: [PATCH 653/838] MAGETWO-57237: Eliminate @escapeNotVerified in Review Module - fixed tests --- .../Review/view/frontend/templates/customer/list.phtml | 4 ++-- app/code/Magento/Review/view/frontend/templates/form.phtml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index 9a17e0ff33f..7d19e34e368 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -34,8 +34,8 @@ <?php if ($_review->getSum()): ?> <div class="rating-summary"> <span class="label"><span><?php echo $block->escapeHtml(__('Rating')) ?>:</span></span> - <div class="rating-result" title="<?php echo ((int)$_review->getSum() / (int)$_review->getCount()) ?>%"> - <span style="width:<?php echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%;"><span><?php echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%</span></span> + <div class="rating-result" title="<?php echo /* @noEscape */ ((int)$_review->getSum() / (int)$_review->getCount()) ?>%"> + <span style="width:<?php /* @noEscape */ echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%;"><span><?php /* @noEscape */ echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%</span></span> </div> </div> <?php endif; ?> diff --git a/app/code/Magento/Review/view/frontend/templates/form.phtml b/app/code/Magento/Review/view/frontend/templates/form.phtml index 04e55e0b118..7c89fd8740c 100644 --- a/app/code/Magento/Review/view/frontend/templates/form.phtml +++ b/app/code/Magento/Review/view/frontend/templates/form.phtml @@ -92,7 +92,7 @@ <?php else: ?> <div class="message info notlogged" id="review-form"> <div> - <?php echo $block->escapeHtml(__('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginLink(), $block->getRegisterUrl(), ['a'])) ?> + <?php echo $block->escapeHtml(__('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginLink(), $block->getRegisterUrl()), ['a']) ?> </div> </div> <?php endif ?> -- GitLab From cf660360b8287a9512fbfd52c3cf822bea5f176b Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Wed, 24 Aug 2016 16:16:25 -0500 Subject: [PATCH 654/838] MAGETWO-55869: Eliminate @escapeNotVerified in Security module - Eliminated @escapeNotVerified from entire module. --- .../templates/page/activity_link.phtml | 6 ++--- .../templates/session/activity.phtml | 26 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml b/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml index 9709002183a..ee3c962a06e 100644 --- a/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml +++ b/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml @@ -11,12 +11,12 @@ */ ?> <a class="link-account-activity" - href="<?php /* @escapeNotVerified */ echo $block->getUrl('security/session/activity') ?>" + href="<?php echo $block->escapeUrl($block->getUrl('security/session/activity')) ?>" id="footer_account_activity" target="_blank" data-mage-init='{"popupWindow": { - "windowURL": "<?php /* @escapeNotVerified */ echo $block->getUrl('security/session/activity') ?>", + "windowURL": "<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/activity'))) ?>", "windowName": "session-activity", "width": 600, "height": 600, "top": 50, "left": 50, "resizable": 1, "scrollbars": 1}}'> - <?php /* @escapeNotVerified */ echo __('Account Activity') ?> + <?php echo $block->escapeHtml(__('Account Activity')) ?> </a> | diff --git a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml index 0dd5139f97f..9ae4c9f62af 100644 --- a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml +++ b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml @@ -14,13 +14,13 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); ?> <header> <div class="page-title-wrapper"> - <h1 class="page-title" align="center"><?php /* @escapeNotVerified */ echo __('Account Activity') ?></h1> + <h1 class="page-title" align="center"><?php echo $block->escapeHtml(__('Account Activity')) ?></h1> <?php if ($block->areMultipleSessionsActive()) { - /* @escapeNotVerified */ echo __( + echo $block->escapeHtml(__( 'This administrator account is open in more than one location. ' .'Note that other locations might be different browsers or sessions on the same computer.' - ); + )); } ?> </div> </header> @@ -28,20 +28,20 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); <div class="page-content"> <?php echo $block->getLayout()->getMessagesBlock()->getGroupedHtml() ?> <div> - <div class="information-title"><?php /* @escapeNotVerified */ echo __('Concurrent session information:')?></div> + <div class="information-title"><?php echo $block->escapeHtml(__('Concurrent session information:'))?></div> <table cellspacing="0" border="1" class="information-table"> <thead> <tr> - <th><?php /* @escapeNotVerified */ echo __('IP Address') ?></th> - <th><?php /* @escapeNotVerified */ echo __('Time of session start') ?></th> + <th><?php echo $block->escapeHtml(__('IP Address')) ?></th> + <th><?php echo $block->escapeHtml(__('Time of session start')) ?></th> </tr> </thead> <tbody> <?php foreach ($sessionInfoCollection as $item):?> <tr> - <td><?php /* @escapeNotVerified */ echo $item->getFormattedIp() ?></td> - <td><?php /* @escapeNotVerified */ echo $block->formatDateTime($item->getCreatedAt()) ?></td> + <td><?php echo $block->escapeHtml($item->getFormattedIp()) ?></td> + <td><?php echo $block->escapeHtml($block->formatDateTime($item->getCreatedAt())) ?></td> </tr> <?php endforeach; @@ -55,18 +55,18 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); if ($block->areMultipleSessionsActive()): ?> data-mage-init='{"confirmRedirect":{ "message": "<?php - /* @escapeNotVerified */ echo __('Are you sure that you want to log out all other sessions?') ?>", - "url":"<?php /* @escapeNotVerified */ echo $block->getUrl('security/session/logoutAll') ?>" + echo $block->escapeJs(__('Are you sure that you want to log out all other sessions?')) ?>", + "url":"<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/logoutAll'))) ?>" }}' <?php else: ?>disabled<?php endif ?> - title="<?php /* @escapeNotVerified */ echo __('Log out all other sessions') ?>"> - <?php /* @escapeNotVerified */ echo __('Log out all other sessions') ?> + title="<?php echo $block->escapeHtmlAttr(__('Log out all other sessions')) ?>"> + <?php echo $block->escapeHtml(__('Log out all other sessions')) ?> </button> </div> <div><?php - /* @escapeNotVerified */ echo __('This computer is using IP address %1.', $block->getRemoteIp()) ?></div> + echo $block->escapeHtml(__('This computer is using IP address %1.', $block->getRemoteIp())) ?></div> </div> </div> -- GitLab From 5ff6c66bc1417d6be9bd0e8958631eb563845846 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Wed, 24 Aug 2016 17:24:37 -0500 Subject: [PATCH 655/838] MAGETWO-55589: Wrong algorithm for calculation batch size on category indexing --- .../Framework/DB/Adapter/Pdo/Mysql.php | 67 +++---- .../Framework/DB/Query/BatchIterator.php | 170 ++++++++++++++++++ .../DB/Query/BatchIteratorFactory.php | 47 +++++ .../Magento/Framework/DB/Query/Generator.php | 90 ++++++++++ 4 files changed, 331 insertions(+), 43 deletions(-) create mode 100644 lib/internal/Magento/Framework/DB/Query/BatchIterator.php create mode 100644 lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php create mode 100644 lib/internal/Magento/Framework/DB/Query/Generator.php diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php index 468885548b3..6399824590a 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php +++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php @@ -26,6 +26,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Phrase; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Stdlib\StringUtils; +use Magento\Framework\DB\Query\Generator as QueryGenerator; /** * @SuppressWarnings(PHPMD.ExcessivePublicCount) @@ -199,6 +200,11 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface */ private $exceptionMap; + /** + * @var QueryGenerator + */ + private $queryGenerator; + /** * @param StringUtils $string * @param DateTime $dateTime @@ -3362,57 +3368,32 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface * @param int $stepCount * @return \Magento\Framework\DB\Select[] * @throws LocalizedException + * @deprecated */ public function selectsByRange($rangeField, \Magento\Framework\DB\Select $select, $stepCount = 100) { - $fromSelect = $select->getPart(\Magento\Framework\DB\Select::FROM); - if (empty($fromSelect)) { - throw new LocalizedException( - new \Magento\Framework\Phrase('Select object must have correct "FROM" part') - ); - } - - $tableName = []; - $correlationName = ''; - foreach ($fromSelect as $correlationName => $formPart) { - if ($formPart['joinType'] == \Magento\Framework\DB\Select::FROM) { - $tableName = $formPart['tableName']; - break; - } - } - - $selectRange = $this->select() - ->from( - $tableName, - [ - new \Zend_Db_Expr('MIN(' . $this->quoteIdentifier($rangeField) . ') AS min'), - new \Zend_Db_Expr('MAX(' . $this->quoteIdentifier($rangeField) . ') AS max'), - ] - ); - - $rangeResult = $this->fetchRow($selectRange); - $min = $rangeResult['min']; - $max = $rangeResult['max']; - + $iterator = $this->getQueryGenerator()->generate($rangeField, $select, $stepCount); $queries = []; - while ($min <= $max) { - $partialSelect = clone $select; - $partialSelect->where( - $this->quoteIdentifier($correlationName) . '.' - . $this->quoteIdentifier($rangeField) . ' >= ?', - $min - ) - ->where( - $this->quoteIdentifier($correlationName) . '.' - . $this->quoteIdentifier($rangeField) . ' < ?', - $min + $stepCount - ); - $queries[] = $partialSelect; - $min += $stepCount; + foreach ($iterator as $query) { + $queries[] = $query; } return $queries; } + /** + * Get query generator + * + * @return QueryGenerator + * @deprecated + */ + private function getQueryGenerator() + { + if ($this->queryGenerator === null) { + $this->queryGenerator = \Magento\Framework\App\ObjectManager::getInstance()->create(QueryGenerator::class); + } + return $this->queryGenerator; + } + /** * Get update table query using select object for join and update * diff --git a/lib/internal/Magento/Framework/DB/Query/BatchIterator.php b/lib/internal/Magento/Framework/DB/Query/BatchIterator.php new file mode 100644 index 00000000000..532d823e8d5 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Query/BatchIterator.php @@ -0,0 +1,170 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\DB\Query; + +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; + +/** + * Query batch iterator + */ +class BatchIterator implements \Iterator +{ + /** + * @var int + */ + private $batchSize; + + /** + * @var Select + */ + private $select; + + /** + * @var int + */ + private $minValue = 0; + + /** + * @var string + */ + private $correlationName; + + /** + * @var string + */ + private $rangeField; + + /** + * @var Select + */ + private $currentSelect; + + /** + * @var AdapterInterface + */ + private $connection; + + /** + * @var int + */ + private $iteration = 0; + + /** + * @var string + */ + private $rangeFieldAlias; + + /** + * Initialize dependencies. + * + * @param Select $select + * @param int $batchSize + * @param string $correlationName + * @param string $rangeField + */ + public function __construct( + Select $select, + $batchSize, + $correlationName, + $rangeField, + $rangeFieldAlias + ) { + $this->batchSize = $batchSize; + $this->select = $select; + $this->correlationName = $correlationName; + $this->rangeField = $rangeField; + $this->rangeFieldAlias = $rangeFieldAlias; + $this->connection = $select->getConnection(); + } + + /** + * @return Select + */ + public function current() + { + return $this->currentSelect; + } + + /** + * @return Select + */ + public function next() + { + $this->iteration++; + return $this->currentSelect; + } + + /** + * @return int + */ + public function key() + { + return $this->iteration; + } + + /** + * @return bool + */ + public function valid() + { + $this->currentSelect = $this->initSelectObject(); + $batchSize = $this->calculateBatchSize($this->currentSelect); + return $batchSize > 0; + } + + /** + * @return void + */ + public function rewind() + { + $this->minValue = 0; + $this->iteration = 0; + } + + /** + * Calculate batch size for select. + * + * @param Select $select + * @return int + */ + private function calculateBatchSize(Select $select) + { + $wrapperSelect = $this->connection->select(); + $wrapperSelect->from( + $select, + [ + new \Zend_Db_Expr('MAX(' . $this->rangeFieldAlias . ') as max'), + new \Zend_Db_Expr('COUNT(*) as cnt') + ] + ); + $row = $this->connection->fetchRow($wrapperSelect); + $this->minValue = $row['max']; + return intval($row['cnt']); + } + + /** + * Initialize select object. + * + * @return \Magento\Framework\DB\Select + */ + private function initSelectObject() + { + $object = clone $this->select; + $object->where( + $this->connection->quoteIdentifier($this->correlationName) + . '.' . $this->connection->quoteIdentifier($this->rangeField) + . ' > ?', + $this->minValue + ); + $object->limit($this->batchSize); + /** + * Reset sort order section from origin select object + */ + $object->order($this->correlationName . '.' . $this->rangeField . ' asc'); + return $object; + } +} diff --git a/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php b/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php new file mode 100644 index 00000000000..8002bfcbf5d --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php @@ -0,0 +1,47 @@ +<?php +namespace Magento\Framework\DB\Query; + +/** + * Factory class for @see \Magento\Framework\DB\Query\BatchIterator + */ +class BatchIteratorFactory +{ + /** + * Object Manager instance + * + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager = null; + + /** + * Instance name to create + * + * @var string + */ + private $instanceName = null; + + /** + * Factory constructor + * + * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @param string $instanceName + */ + public function __construct( + \Magento\Framework\ObjectManagerInterface $objectManager, + $instanceName = \Magento\Framework\DB\Query\BatchIterator::class + ) { + $this->objectManager = $objectManager; + $this->instanceName = $instanceName; + } + + /** + * Create class instance with specified parameters + * + * @param array $data + * @return \Magento\Framework\DB\Query\BatchIterator + */ + public function create(array $data = array()) + { + return $this->objectManager->create($this->instanceName, $data); + } +} diff --git a/lib/internal/Magento/Framework/DB/Query/Generator.php b/lib/internal/Magento/Framework/DB/Query/Generator.php new file mode 100644 index 00000000000..45778898a46 --- /dev/null +++ b/lib/internal/Magento/Framework/DB/Query/Generator.php @@ -0,0 +1,90 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\DB\Query; + +use Magento\Framework\Exception\LocalizedException; + +/** + * Query generator + */ +class Generator +{ + /** + * @var \Magento\Framework\DB\Query\BatchIteratorFactory + */ + private $iteratorFactory; + + /** + * Initialize dependencies. + * + * @param BatchIteratorFactory $iteratorFactory + */ + public function __construct(BatchIteratorFactory $iteratorFactory) + { + $this->iteratorFactory = $iteratorFactory; + } + + /** + * Generate select query list with predefined items count in each select item. + * + * @param string $rangeField + * @param \Magento\Framework\DB\Select $select + * @param int $batchSize + * @return BatchIterator + * @throws LocalizedException + */ + public function generate($rangeField, \Magento\Framework\DB\Select $select, $batchSize = 100) + { + $fromSelect = $select->getPart(\Magento\Framework\DB\Select::FROM); + if (empty($fromSelect)) { + throw new LocalizedException( + new \Magento\Framework\Phrase('Select object must have correct "FROM" part') + ); + } + + $fieldCorrelationName = ''; + foreach ($fromSelect as $correlationName => $formPart) { + if ($formPart['joinType'] == \Magento\Framework\DB\Select::FROM) { + $fieldCorrelationName = $correlationName; + break; + } + } + + $columns = $select->getPart(\Magento\Framework\DB\Select::COLUMNS); + /** + * Calculate $rangeField alias + */ + $rangeFieldAlias = null; + foreach ($columns as $column) { + list($table, $columnName, $alias) = $column; + if (is_string($table) && is_string($columnName) + && $table == $fieldCorrelationName && $columnName == $rangeField + ) { + $rangeFieldAlias = $alias; + break; + } + } + + if (!$rangeFieldAlias) { + throw new LocalizedException( + new \Magento\Framework\Phrase( + 'Select object must have correct range field name %field', + ['field' => $rangeField] + ) + ); + } + + return $this->iteratorFactory->create( + [ + 'select' => $select, + 'batchSize' => $batchSize, + 'correlationName' => $fieldCorrelationName, + 'rangeField' => $rangeField, + 'rangeFieldAlias' => $rangeFieldAlias + ] + ); + } +} -- GitLab From 6ae23bcd7c082dd0c8b8d812fdd78cf44ca4058f Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 24 Aug 2016 17:54:01 -0500 Subject: [PATCH 656/838] MAGETWO-54779: [GitHub] Image size for Product Watermarks can't be set #5270 - fixing field for swatches image --- .../view/adminhtml/ui_component/design_config_form.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml index 1b5ec69e5d5..0891fb35183 100644 --- a/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml +++ b/app/code/Magento/Swatches/view/adminhtml/ui_component/design_config_form.xml @@ -48,12 +48,13 @@ <field name="watermark_swatch_image_size"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Catalog/component/image-size-field</item> <item name="label" xsi:type="string" translate="true">Image Size</item> <item name="dataType" xsi:type="string">text</item> <item name="formElement" xsi:type="string">input</item> <item name="dataScope" xsi:type="string">watermark_swatch_image_size</item> <item name="validation" xsi:type="array"> - <item name="validate-digits" xsi:type="boolean">true</item> + <item name="validate-image-size-range" xsi:type="boolean">true</item> </item> <item name="notice" xsi:type="string" translate="true">Example format: 200x300.</item> </item> -- GitLab From 6e82b6755df962cf7654cc783296c147ac75c55e Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Wed, 24 Aug 2016 18:00:06 -0500 Subject: [PATCH 657/838] MAGETWO-55589: Wrong algorithm for calculation batch size on category indexing - CR changes --- .../Magento/Framework/DB/Query/BatchIterator.php | 1 + .../Framework/DB/Query/BatchIteratorFactory.php | 6 +++++- lib/internal/Magento/Framework/DB/Query/Generator.php | 10 ++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/DB/Query/BatchIterator.php b/lib/internal/Magento/Framework/DB/Query/BatchIterator.php index 532d823e8d5..86a1a73a20c 100644 --- a/lib/internal/Magento/Framework/DB/Query/BatchIterator.php +++ b/lib/internal/Magento/Framework/DB/Query/BatchIterator.php @@ -65,6 +65,7 @@ class BatchIterator implements \Iterator * @param int $batchSize * @param string $correlationName * @param string $rangeField + * @param string $rangeFieldAlias */ public function __construct( Select $select, diff --git a/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php b/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php index 8002bfcbf5d..a51a650197d 100644 --- a/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php +++ b/lib/internal/Magento/Framework/DB/Query/BatchIteratorFactory.php @@ -1,4 +1,8 @@ <?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Framework\DB\Query; /** @@ -40,7 +44,7 @@ class BatchIteratorFactory * @param array $data * @return \Magento\Framework\DB\Query\BatchIterator */ - public function create(array $data = array()) + public function create(array $data = []) { return $this->objectManager->create($this->instanceName, $data); } diff --git a/lib/internal/Magento/Framework/DB/Query/Generator.php b/lib/internal/Magento/Framework/DB/Query/Generator.php index 45778898a46..1873418968b 100644 --- a/lib/internal/Magento/Framework/DB/Query/Generator.php +++ b/lib/internal/Magento/Framework/DB/Query/Generator.php @@ -46,8 +46,8 @@ class Generator } $fieldCorrelationName = ''; - foreach ($fromSelect as $correlationName => $formPart) { - if ($formPart['joinType'] == \Magento\Framework\DB\Select::FROM) { + foreach ($fromSelect as $correlationName => $fromPart) { + if ($fromPart['joinType'] == \Magento\Framework\DB\Select::FROM) { $fieldCorrelationName = $correlationName; break; } @@ -60,9 +60,7 @@ class Generator $rangeFieldAlias = null; foreach ($columns as $column) { list($table, $columnName, $alias) = $column; - if (is_string($table) && is_string($columnName) - && $table == $fieldCorrelationName && $columnName == $rangeField - ) { + if (is_string($columnName) && $table == $fieldCorrelationName && $columnName == $rangeField) { $rangeFieldAlias = $alias; break; } @@ -71,7 +69,7 @@ class Generator if (!$rangeFieldAlias) { throw new LocalizedException( new \Magento\Framework\Phrase( - 'Select object must have correct range field name %field', + 'Select object must have correct range field name "%field"', ['field' => $rangeField] ) ); -- GitLab From 2833639b6d2629817ed2fd8a6072009f9b27b495 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Thu, 25 Aug 2016 12:54:00 +0300 Subject: [PATCH 658/838] MAGETWO-56819: Notification messages area. Pull request preparation. --- .../view/adminhtml/web/js/grid/columns/message.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js index dc80d136bb4..aa5477ebafc 100644 --- a/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js +++ b/app/code/Magento/AdminNotification/view/adminhtml/web/js/grid/columns/message.js @@ -20,9 +20,9 @@ define([ 'message-error': false }, statusMap: { - 0: 'success', + 0: 'info', 1: 'progress', - 2: 'info', + 2: 'success', 3: 'error' } }, -- GitLab From f5a60e9a3bff1bae1d9b24ac225b566dca1117b2 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Thu, 25 Aug 2016 12:49:10 +0300 Subject: [PATCH 659/838] MAGETWO-54458: Scope selector on product page does not display all related websites for restricted user --- .../Magento/Backend/Block/Store/Switcher.php | 2 - .../Test/Unit/Block/Store/SwitcherTest.php | 53 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php diff --git a/app/code/Magento/Backend/Block/Store/Switcher.php b/app/code/Magento/Backend/Block/Store/Switcher.php index eb113e45c45..cd15704952b 100644 --- a/app/code/Magento/Backend/Block/Store/Switcher.php +++ b/app/code/Magento/Backend/Block/Store/Switcher.php @@ -8,8 +8,6 @@ namespace Magento\Backend\Block\Store; /** * Store switcher block - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Switcher extends \Magento\Backend\Block\Template { diff --git a/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php b/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php new file mode 100644 index 00000000000..e0229d54ba2 --- /dev/null +++ b/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Backend\Test\Unit\Block\Cache; + +class SwitcherTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Backend\Block\Store\Switcher + */ + private $switcherBlock; + + private $storeManagerMock; + + protected function setUp() + { + $this->storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManagerInterface::class); + $objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $context = $objectHelper->getObject( + \Magento\Backend\Block\Template\Context::class, + [ + 'storeManager' => $this->storeManagerMock, + ] + ); + + $this->switcherBlock = $objectHelper->getObject( + \Magento\Backend\Block\Store\Switcher::class, + ['context' => $context] + ); + } + + public function testGetWebsites() + { + $websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false); + $websites = [0 => $websiteMock, 1 => $websiteMock]; + $this->storeManagerMock->expects($this->once())->method('getWebsites')->will($this->returnValue($websites)); + $this->assertEquals($websites, $this->switcherBlock->getWebsites()); + } + + public function testGetWebsitesIfSetWebsiteIds() + { + $websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false); + $websites = [0 => $websiteMock, 1 => $websiteMock]; + $this->storeManagerMock->expects($this->once())->method('getWebsites')->will($this->returnValue($websites)); + + $this->switcherBlock->setWebsiteIds([1]); + $expected = [1 => $websiteMock]; + $this->assertEquals($expected, $this->switcherBlock->getWebsites()); + } +} -- GitLab From 3ce8f20bf51f6278d8972eac973ea8c16b978438 Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Thu, 25 Aug 2016 14:24:34 +0300 Subject: [PATCH 660/838] MAGETWO-54134: CE module depends on EE code - Fixed unit test --- .../Usps/Test/Unit/Model/CarrierTest.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php index 1e2e9fd797b..a79206553c5 100644 --- a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php +++ b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php @@ -6,6 +6,7 @@ namespace Magento\Usps\Test\Unit\Model; use Magento\Quote\Model\Quote\Address\RateRequest; +use Magento\Usps\Helper\Data as DataHelper; use Magento\Usps\Model\Carrier; /** @@ -43,6 +44,11 @@ class CarrierTest extends \PHPUnit_Framework_TestCase */ protected $scope; + /** + * @var DataHelper|\PHPUnit_Framework_MockObject_MockObject + */ + private $dataHelper; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -154,7 +160,14 @@ class CarrierTest extends \PHPUnit_Framework_TestCase ]; + $this->dataHelper = $this->getMockBuilder(DataHelper::class) + ->disableOriginalConstructor() + ->setMethods(['displayGirthValue']) + ->getMock(); + $this->carrier = $this->helper->getObject(\Magento\Usps\Model\Carrier::class, $arguments); + + $this->helper->setBackwardCompatibleProperty($this->carrier, 'dataHelper', $this->dataHelper); } /** @@ -324,4 +337,33 @@ class CarrierTest extends \PHPUnit_Framework_TestCase ], ]; } + + /** + * @param string $countyCode + * @param string $carrierMethodCode + * @param bool $displayGirthValueResult + * @param bool $result + * @dataProvider isGirthAllowedDataProvider + */ + public function testIsGirthAllowed($countyCode, $carrierMethodCode, $displayGirthValueResult, $result) + { + $this->dataHelper->expects(static::any()) + ->method('displayGirthValue') + ->with($carrierMethodCode) + ->willReturn($displayGirthValueResult); + + self::assertEquals($result, $this->carrier->isGirthAllowed($countyCode, $carrierMethodCode)); + } + + /** + * @return array + */ + public function isGirthAllowedDataProvider() + { + return [ + ['US', 'usps_1', true, false], + ['UK', 'usps_1', true, true], + ['US', 'usps_0', false, true], + ]; + } } -- GitLab From e8376bfb9432c34c8ef70a24824b524414ab99e5 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Thu, 25 Aug 2016 14:39:36 +0300 Subject: [PATCH 661/838] MAGETWO-54458: Scope selector on product page does not display all related websites for restricted user --- app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php b/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php index e0229d54ba2..a4ba16ea1bd 100644 --- a/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php +++ b/app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Backend\Test\Unit\Block\Cache; +namespace Magento\Backend\Test\Unit\Block\Store; class SwitcherTest extends \PHPUnit_Framework_TestCase { -- GitLab From ddb1eea3d3db5664578bb85c739373b292226ad6 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Thu, 25 Aug 2016 14:54:41 +0300 Subject: [PATCH 662/838] MAGETWO-55757: Magento 2 does not work on Apache php-fpm environment --- .htaccess | 24 ++++++++++++++++++++++++ pub/.htaccess | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/.htaccess b/.htaccess index f3dbe217081..af9470488c6 100644 --- a/.htaccess +++ b/.htaccess @@ -32,6 +32,7 @@ DirectoryIndex index.php +<IfModule mod_php5.c> ############################################ ## adjust memory limit @@ -53,7 +54,30 @@ ## disable user agent verification to not break multiple image upload php_flag suhosin.session.cryptua off +</IfModule> +<IfModule mod_php7.c> +############################################ +## adjust memory limit + + php_value memory_limit 768M + php_value max_execution_time 18000 + +############################################ +## disable automatic session start +## before autoload was initialized + + php_flag session.auto_start off + +############################################ +## enable resulting html compression + + #php_flag zlib.output_compression on +########################################### +## disable user agent verification to not break multiple image upload + + php_flag suhosin.session.cryptua off +</IfModule> <IfModule mod_security.c> ########################################### ## disable POST processing to not break multiple image upload diff --git a/pub/.htaccess b/pub/.htaccess index a8fc2ccf222..ecdaf1758a9 100644 --- a/pub/.htaccess +++ b/pub/.htaccess @@ -32,6 +32,7 @@ DirectoryIndex index.php +<IfModule mod_php5.c> ############################################ ## Adjust memory limit @@ -53,6 +54,31 @@ # Disable user agent verification to not break multiple image upload php_flag suhosin.session.cryptua off +</IfModule> +<IfModule mod_php7.c> +############################################ +## Adjust memory limit + + php_value memory_limit 768M + php_value max_execution_time 18000 + +############################################ +## Disable automatic session start +## before autoload was initialized + + php_flag session.auto_start off + +############################################ +## Enable resulting html compression + + #php_flag zlib.output_compression on + +########################################### +# Disable user agent verification to not break multiple image upload + + php_flag suhosin.session.cryptua off +</IfModule> + <IfModule mod_security.c> ########################################### -- GitLab From de9c3b8f761cc6e50f971bf75a3514e72d460f9f Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Thu, 25 Aug 2016 14:57:21 +0300 Subject: [PATCH 663/838] MAGETWO-55908: Prepare PR --- .../Adminhtml/Order/Create/Form/AbstractForm.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php index 6287af52bb8..45d120db475 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php @@ -194,12 +194,17 @@ abstract class AbstractForm extends \Magento\Sales\Block\Adminhtml\Order\Create\ if ($inputType == 'select' || $inputType == 'multiselect') { $options = []; foreach ($attribute->getOptions() as $optionData) { - $options[] = ConvertArray::toFlatArray( - $this->dataObjectProcessor->buildOutputDataArray( - $optionData, - \Magento\Customer\Api\Data\OptionInterface::class - ) + $data = $this->dataObjectProcessor->buildOutputDataArray( + $optionData, + \Magento\Customer\Api\Data\OptionInterface::class ); + foreach ($data as $key => $value) { + if (is_array($value)) { + unset($data[$key]); + $data['value'] = $value; + } + } + $options[] = $data; } $element->setValues($options); } elseif ($inputType == 'date') { -- GitLab From 9b0d94baa6106e7749ccf9be94556b7bed2d4fc9 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <okolesnyk@magento.com> Date: Thu, 25 Aug 2016 15:01:28 +0300 Subject: [PATCH 664/838] MTA-3464: Merge Domain Functional Bamboo Plan --- dev/tests/functional/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json index 4e36f1fa54f..936c4b968af 100644 --- a/dev/tests/functional/composer.json +++ b/dev/tests/functional/composer.json @@ -1,6 +1,6 @@ { "require": { - "magento/mtf": "1.0.0-rc46", + "magento/mtf": "1.0.0-rc47", "php": "~5.6.0|7.0.2|~7.0.6", "phpunit/phpunit": "4.1.0", "phpunit/phpunit-selenium": ">=1.2" -- GitLab From 81031ad7a640344a8872b1c4172a4bcd193e2d92 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Thu, 25 Aug 2016 15:51:49 +0300 Subject: [PATCH 665/838] MAGETWO-55908: Prepare PR --- app/code/Magento/Catalog/etc/extension_attributes.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/etc/extension_attributes.xml b/app/code/Magento/Catalog/etc/extension_attributes.xml index e333c13bcc6..509c3240bb6 100644 --- a/app/code/Magento/Catalog/etc/extension_attributes.xml +++ b/app/code/Magento/Catalog/etc/extension_attributes.xml @@ -13,6 +13,9 @@ <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface"> <attribute code="website_ids" type="int[]"/> </extension_attributes> + <extension_attributes for="Magento\Catalog\Api\Data\ProductOptionInterface"> + <attribute code="custom_options" type="Magento\Catalog\Api\Data\CustomOptionInterface[]" /> + </extension_attributes> <extension_attributes for="Magento\Catalog\Api\Data\CustomOptionInterface"> <attribute code="file_info" type="Magento\Framework\Api\Data\ImageContentInterface"/> </extension_attributes> -- GitLab From 4b2a9d1ec90e20f977562a24b244b157b706333b Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 25 Aug 2016 07:55:06 -0500 Subject: [PATCH 666/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../Block/Account/AuthenticationPopup.php | 8 ++++---- .../templates/system/config/validatevat.phtml | 6 +++--- .../view/adminhtml/templates/tab/cart.phtml | 16 ++++++++-------- .../templates/account/authentication-popup.phtml | 2 +- .../view/frontend/templates/address/book.phtml | 4 ++-- .../view/frontend/templates/address/edit.phtml | 6 +++--- .../view/frontend/templates/form/register.phtml | 6 +++--- .../view/frontend/templates/logout.phtml | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Customer/Block/Account/AuthenticationPopup.php b/app/code/Magento/Customer/Block/Account/AuthenticationPopup.php index 5eb4f7fe055..e09b528e9d4 100644 --- a/app/code/Magento/Customer/Block/Account/AuthenticationPopup.php +++ b/app/code/Magento/Customer/Block/Account/AuthenticationPopup.php @@ -43,10 +43,10 @@ class AuthenticationPopup extends \Magento\Framework\View\Element\Template public function getConfig() { return [ - 'autocomplete' => $this->isAutocompleteEnabled(), - 'customerRegisterUrl' => $this->getCustomerRegisterUrlUrl(), - 'customerForgotPasswordUrl' => $this->getCustomerForgotPasswordUrl(), - 'baseUrl' => $this->getBaseUrl() + 'autocomplete' => $this->escapeHtml($this->isAutocompleteEnabled()), + 'customerRegisterUrl' => $this->escapeUrl($this->getCustomerRegisterUrlUrl()), + 'customerForgotPasswordUrl' => $this->escapeUrl($this->getCustomerForgotPasswordUrl()), + 'baseUrl' => $this->escapeUrl($this->getBaseUrl()) ]; } diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index 77cc24e1b87..18f843d6566 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -16,11 +16,11 @@ require(['prototype'], function(){ var validationMessage = $('validation_result'); params = { - country: $('<?php echo $block->escapeJs($block->getMerchantCountryField()); ?>').value, - vat: $('<?php echo $block->escapeJs($block->getMerchantVatNumberField()); ?>').value + country: $('<?php echo $block->escapeJs($block->escapeHtml($block->getMerchantCountryField())); ?>').value, + vat: $('<?php echo $block->escapeJs($block->escapeHtml($block->getMerchantVatNumberField())); ?>').value }; - new Ajax.Request('<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>', { + new Ajax.Request('<?php echo $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>', { parameters: params, onSuccess: function(response) { var result = '<?php echo $block->escapeJs($block->escapeHtml(__('Error during VAT Number verification.'))) ?>'; diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index f8ca555c2ad..c11ea7aa3bc 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -34,14 +34,14 @@ require([ if (!params) { params = {}; } - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = params; - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reload(); - <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = {}; + <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.reloadParams = params; + <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.reload(); + <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.reloadParams = {}; }, configureItem: function (itemId) { - productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($listType) ?>', this.cbOnLoadIframe.bind(this)); - productConfigure.showItemConfiguration('<?php echo $block->escapeJs($listType) ?>', itemId); + productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($block->escapeHtml($listType)) ?>', this.cbOnLoadIframe.bind(this)); + productConfigure.showItemConfiguration('<?php echo $block->escapeJs($block->escapeHtml($listType)) ?>', itemId); return false; }, @@ -81,10 +81,10 @@ $params = [ ]; ?> productConfigure.addListType( - '<?php echo $block->escapeJs($listType) ?>', + '<?php echo $block->escapeJs($block->escapeHtml($listType)) ?>', { - urlFetch: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/configure', $params)) ?>', - urlConfirm: '<?php echo $block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/update', $params)) ?>' + urlFetch: '<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/configure', $params))) ?>', + urlConfirm: '<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/update', $params))) ?>' } ); diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index 2b62b1f6fb7..f34cc41344e 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -19,7 +19,7 @@ "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> }, "*": { - "Magento_Ui/js/block-loader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-1.gif')); ?>" + "Magento_Ui/js/block-loader": "<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('images/loader-1.gif'))); ?>" } } </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index fe45a6132b0..37ab2584c84 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -99,9 +99,9 @@ ".page-main": { "address": { "deleteAddress": "li.item a[role='delete-address']", - "deleteUrlPrefix": "<?php echo $block->escapeUrl($block->getDeleteUrl()) ?>id/", + "deleteUrlPrefix": "<?php echo $block->escapeJs($block->escapeUrl($block->getDeleteUrl())) ?>id/", "addAddress": "button[role='add-address']", - "addAddressLocation": "<?php echo $block->escapeUrl($block->getAddAddressUrl()) ?>" + "addAddressLocation": "<?php echo $block->escapeJs($block->escapeUrl($block->getAddAddressUrl())) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index 15986ca8a6c..f721db9a39c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -212,9 +212,9 @@ "regionInputId": "#region", "postcodeId": "#zip", "form": "#form-validate", - "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->getRegionId()) ?>", - "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> + "regionJson": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getRegionJson() ?>, + "defaultRegion": "<?php echo $block->escapeJs($block->escapeHtml($block->getRegionId())) ?>", + "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getCountriesWithOptionalZip(true) ?> } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index 892179e738a..fb51e056d16 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -209,9 +209,9 @@ require([ "regionInputId": "#region", "postcodeId": "#zip", "form": "#form-validate", - "regionJson": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->getFormData()->getRegionId()) ?>", - "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?> + "regionJson": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getRegionJson() ?>, + "defaultRegion": "<?php echo $block->escapeJs($block->escapeHtml($block->getFormData()->getRegionId())) ?>", + "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getCountriesWithOptionalZip(true) ?> } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/logout.phtml b/app/code/Magento/Customer/view/frontend/templates/logout.phtml index 4233fd95287..c866a0d091f 100644 --- a/app/code/Magento/Customer/view/frontend/templates/logout.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/logout.phtml @@ -13,7 +13,7 @@ require([ "mage/mage" ], function($){ - $($.mage.redirect("<?php echo $block->escapeUrl($block->getUrl()) ?>", "assign", 5000)); + $($.mage.redirect("<?php echo $block->escapeJs($block->escapeUrl($block->getUrl())) ?>", "assign", 5000)); }); </script> -- GitLab From 87ee82fe971cf3d8bac644d8032662564d7e1670 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 25 Aug 2016 08:09:32 -0500 Subject: [PATCH 667/838] MAGETWO-57233: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../Magento/Captcha/view/adminhtml/templates/default.phtml | 2 +- app/code/Magento/Cookie/Block/RequireCookie.php | 5 ++++- app/code/Magento/Cookie/Helper/Cookie.php | 2 +- .../Cookie/view/frontend/templates/html/notices.phtml | 2 +- .../Magento/SendFriend/view/frontend/templates/send.phtml | 6 +++--- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml index 2972080063c..1246f1f4f5d 100644 --- a/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml +++ b/app/code/Magento/Captcha/view/adminhtml/templates/default.phtml @@ -45,7 +45,7 @@ $captcha = $block->getCaptchaModel(); require(["prototype", "mage/captcha"], function(){ //<![CDATA[ - var captcha = new Captcha('<?php echo $block->escapeUrl($block->getRefreshUrl()) ?>', '<?php echo $block->escapeJs($block->getFormId()) ?>'); + var captcha = new Captcha('<?php echo $block->escapeJs($block->escapeUrl($block->getRefreshUrl())) ?>', '<?php echo $block->escapeJs($block->escapeHtml($block->getFormId())) ?>'); $('captcha-reload').observe('click', function () { captcha.refresh(this); diff --git a/app/code/Magento/Cookie/Block/RequireCookie.php b/app/code/Magento/Cookie/Block/RequireCookie.php index 94e457f4cff..befecd2cf63 100644 --- a/app/code/Magento/Cookie/Block/RequireCookie.php +++ b/app/code/Magento/Cookie/Block/RequireCookie.php @@ -18,7 +18,10 @@ class RequireCookie extends \Magento\Framework\View\Element\Template */ public function getScriptOptions() { - $params = ['noCookieUrl' => $this->getUrl('cookie/index/noCookies/'), 'triggers' => $this->getTriggers()]; + $params = [ + 'noCookieUrl' => $this->escapeUrl($this->getUrl('cookie/index/noCookies/')), + 'triggers' => $this->escapeHtml($this->getTriggers()) + ]; return json_encode($params); } } diff --git a/app/code/Magento/Cookie/Helper/Cookie.php b/app/code/Magento/Cookie/Helper/Cookie.php index e381162c887..8416165f8c7 100644 --- a/app/code/Magento/Cookie/Helper/Cookie.php +++ b/app/code/Magento/Cookie/Helper/Cookie.php @@ -84,7 +84,7 @@ class Cookie extends \Magento\Framework\App\Helper\AbstractHelper public function getAcceptedSaveCookiesWebsiteIds() { $acceptedSaveCookiesWebsites = $this->_getAcceptedSaveCookiesWebsites(); - $acceptedSaveCookiesWebsites[$this->_website->getId()] = 1; + $acceptedSaveCookiesWebsites[(int)$this->_website->getId()] = 1; return json_encode($acceptedSaveCookiesWebsites); } diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index d34214a3f7b..e8e6d932950 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -30,7 +30,7 @@ "cookieName": "<?php /* @noEscape */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", "cookieValue": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getAcceptedSaveCookiesWebsiteIds() ?>, "cookieLifetime": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getCookieRestrictionLifetime()?>, - "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" + "noCookiesUrl": "<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('cookie/index/noCookies'))) ?>" } } } diff --git a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml index 4f52f5026bb..68902718907 100644 --- a/app/code/Magento/SendFriend/view/frontend/templates/send.phtml +++ b/app/code/Magento/SendFriend/view/frontend/templates/send.phtml @@ -17,13 +17,13 @@ <div class="secondary"> <button type="button" id="btn-remove<%- data._index_ %>" class="action remove" title="<?php echo $block->escapeHtmlAttr(__('Remove Recipent')) ?>"> - <span><?php echo $block->escapeHtml(__('Remove')) ?></span> + <span><?php echo $block->escapeJs($block->escapeHtml(__('Remove'))) ?></span> </button> </div> </div> <fieldset class="fieldset"> <div class="field name required"> - <label for="recipients-name<%- data._index_ %>" class="label"><span><?php echo $block->escapeHtml(__('Name')) ?></span></label> + <label for="recipients-name<%- data._index_ %>" class="label"><span><?php echo $block->escapeJs($block->escapeHtml(__('Name'))) ?></span></label> <div class="control"> <input name="recipients[name][<%- data._index_ %>]" type="text" title="<?php echo $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><?php echo $block->escapeHtml(__('Email')) ?></span></label> + <label for="recipients-email<%- data._index_ %>" class="label"><span><?php echo $block->escapeJs($block->escapeHtml(__('Email'))) ?></span></label> <div class="control"> <input name="recipients[email][<%- data._index_ %>]" title="<?php echo $block->escapeHtmlAttr(__('Email')) ?>" id="recipients-email<%- data._index_ %>" type="email" class="input-text" -- GitLab From 508c2497317af3866a06e2c5ca97b10b349e0ed3 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 25 Aug 2016 08:55:53 -0500 Subject: [PATCH 668/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 107 +++++++++++++-------- 1 file changed, 68 insertions(+), 39 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 14cab9eefe4..c3ad8ab90d6 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -55,42 +55,78 @@ class Escaper */ private function escapeHtmlTagsAndAttributes($string, $allowedTags) { - $allowedTags = implode('|', $allowedTags); - $allowedAttributes = implode('|', $this->allowedAttributes); - - $attributeReplacements = []; + $tagReplacements = []; $string = preg_replace_callback( - '/(' . $allowedAttributes . ')=[\'"](.*?)[\'"]/si', - function ($matches) use (&$attributeReplacements) { - $result = $matches[1] . '=-=quote=--=attribute-value-' . count($attributeReplacements) . '=--=quote=-'; - $attributeReplacements[] = [ - 'name' => $matches[1], - 'value' => $matches[2] - ]; + '/<.+?>/si', + function ($matches) use (&$tagReplacements) { + $result = '-=replacement-' . count($tagReplacements) . '=-'; + $tagReplacements[] = $matches[0]; return $result; }, $string ); - $string = preg_replace( - '/<([\/\s\r\n]*)(' . $allowedTags . ')([^>]*)([\/\s\r\n]*)>/si', - '##$1$2$3$4##', - $string - ); - $string = $this->escapeHtml($string); - $string = preg_replace( - '/##([\/\s\r\n]*)(' . $allowedTags . ')([^##]*)([\/\s\r\n]*)##/si', - '<$1$2$3$4>', - $string - ); + $newTagReplacements = []; + foreach ($tagReplacements as $tagReplacementKey => $tagReplacement) { + $isClosing = substr($tagReplacement, 0, 2) == '</'; + $isSelfClosing = substr($tagReplacement, -2) == '/>'; - $attributeReplacements = $this->escapeAttributeValues($attributeReplacements); + if (!$isClosing) { + $tagReplacement = str_replace(['&', '<', '>'], ['&', '<', '>'], $tagReplacement); + $length = strlen($tagReplacement); + $end = substr($tagReplacement, -2); + + set_error_handler( + function($errorNumber, $errorString, $errorFile, $errorLine) { + throw new \Exception($errorString, $errorNumber); + } + ); + try { + $tag = new \SimpleXMLElement( + $end == '/>' ? $tagReplacement : (substr($tagReplacement, 0, $length-1) . ' />') + ); + } catch (\Exception $e) { + $newTagReplacements[$tagReplacementKey] = ''; + restore_error_handler(); + continue; + } + restore_error_handler(); + $tagName = $tag->getName(); + } else { + $tagName = trim($tagReplacement, '<>/'); + } + + if (!in_array($tagName, $allowedTags)) { + $newTagReplacements[$tagReplacementKey] = ''; + continue; + } + + $attributes = []; + if (!$isClosing && $tag->attributes()) { + foreach ($tag->attributes() as $attributeName => $attributeValue) { + if (in_array($attributeName, $this->allowedAttributes)) { + $attributes[] = $attributeName . '="' + . $this->escapeAttributeValue( + $attributeName, + str_replace(['&', '<', '>'], ['&', '<', '>'], $attributeValue) + ) + . '"'; + } + } + $newTagReplacements[$tagReplacementKey] = '<' . $tagName . ' ' . implode(' ', $attributes) . '>'; + } else { + $newTagReplacements[$tagReplacementKey] = $isSelfClosing + ? '<' . $tagName . ' />' : '</' . $tagName . '>'; + } + } + + $string = $this->escapeHtml($string); $string = preg_replace_callback( - '/-=quote=--=attribute-value-(\d)=--=quote=-/si', - function($matches) use (&$attributeReplacements) { - return '"' . $attributeReplacements[$matches[1]]['value'] . '"'; + '/-=replacement-(\d)=-/si', + function($matches) use ($newTagReplacements) { + return $newTagReplacements[$matches[1]]; }, $string ); @@ -99,22 +135,15 @@ class Escaper } /** - * Escape attribute values using escapeHtmlAttr and escapeUrl depending on the attribute. $attributes has the - * following structure [['name' => 'id', 'value' => 'identifier'], ['name' => 'href', 'value' => 'http://abc.com/']] + * Escape attribute values using escapeHtmlAttr or escapeUrl depending on the attribute * - * @param array $attributes - * @return array + * @param string $name + * @param string $value + * @return string */ - private function escapeAttributeValues($attributes) + private function escapeAttributeValue($name, $value) { - foreach ($attributes as $key => $attribute) { - if ($attribute['name'] == 'href') { - $attributes[$key]['value'] = $this->escapeHtml($attribute['value']); - } else { - $attributes[$key]['value'] = $this->escapeHtmlAttr($attribute['value']); - } - } - return $attributes; + return $name == 'href' ? $this->escapeUrl($value) : $this->escapeHtml($value); } /** -- GitLab From 49a08f2a5e2d62ba0aefc5882d5e3109af74a576 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Thu, 25 Aug 2016 17:26:44 +0300 Subject: [PATCH 669/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- .../Setup/Controller/SelectVersion.php | 2 +- .../src/Magento/Setup/Model/SystemPackage.php | 69 ++++++++++--------- .../Test/Unit/Model/SystemPackageTest.php | 67 +++++++++--------- 3 files changed, 71 insertions(+), 67 deletions(-) diff --git a/setup/src/Magento/Setup/Controller/SelectVersion.php b/setup/src/Magento/Setup/Controller/SelectVersion.php index 5b1d11058fc..96bdb73ac3c 100644 --- a/setup/src/Magento/Setup/Controller/SelectVersion.php +++ b/setup/src/Magento/Setup/Controller/SelectVersion.php @@ -71,7 +71,7 @@ class SelectVersion extends AbstractActionController { $data = []; try { - $data['packages'] = $this->systemPackage->getInstalledSystemPackages([]); + $data['packages'] = $this->systemPackage->getInstalledSystemPackages(); $data['responseType'] = ResponseTypeInterface::RESPONSE_TYPE_SUCCESS; } catch (\Exception $e) { $data['error'] = $e->getMessage(); diff --git a/setup/src/Magento/Setup/Model/SystemPackage.php b/setup/src/Magento/Setup/Model/SystemPackage.php index de2df00347c..2b8bcf8166c 100755 --- a/setup/src/Magento/Setup/Model/SystemPackage.php +++ b/setup/src/Magento/Setup/Model/SystemPackage.php @@ -31,6 +31,10 @@ class SystemPackage */ private $composerInfo; + const EDITION_COMMUNITY = 'magento/product-community-edition'; + const EDITION_ENTERPRISE = 'magento/product-enterprise-edition'; + const EDITION_B2B = 'magento/product-b2b-edition'; + /** * Constructor * @@ -58,8 +62,7 @@ class SystemPackage $currentEE = $currentCE; $result = []; - $systemPackages = []; - $systemPackages = $this->getInstalledSystemPackages($systemPackages); + $systemPackages = $this->getInstalledSystemPackages(); foreach ($systemPackages as $systemPackage) { $systemPackageInfo = $this->infoCommand->run($systemPackage); if (!$systemPackageInfo) { @@ -68,11 +71,11 @@ class SystemPackage $versions = $this->getSystemPackageVersions($systemPackageInfo); - if ($systemPackageInfo['name'] == 'magento/product-community-edition') { + if ($systemPackageInfo['name'] == static::EDITION_COMMUNITY) { $currentCE = $systemPackageInfo[InfoCommand::CURRENT_VERSION]; } - if ($systemPackageInfo['name'] == 'magento/product-enterprise-edition') { + if ($systemPackageInfo['name'] == static::EDITION_ENTERPRISE) { $currentEE = $systemPackageInfo[InfoCommand::CURRENT_VERSION]; } @@ -86,13 +89,13 @@ class SystemPackage ]; } - if (!in_array('magento/product-enterprise-edition', $systemPackages)) { + if (!in_array(static::EDITION_ENTERPRISE, $systemPackages)) { $result = array_merge($this->getAllowedEnterpriseVersions($currentCE), $result); } if ( - in_array('magento/product-enterprise-edition', $systemPackages) - && !in_array('magento/product-b2b-edition', $systemPackages) + in_array(static::EDITION_ENTERPRISE, $systemPackages) + && !in_array(static::EDITION_B2B, $systemPackages) ) { $result = array_merge($this->getAllowedB2BVersions($currentEE), $result); } @@ -111,20 +114,20 @@ class SystemPackage public function getAllowedEnterpriseVersions($currentCE) { $result = []; - $enterpriseVersions = $this->infoCommand->run('magento/product-enterprise-edition'); + $enterpriseVersions = $this->infoCommand->run(static::EDITION_ENTERPRISE); $eeVersions = []; $maxVersion = ''; - if (is_array($enterpriseVersions) && array_key_exists('available_versions', $enterpriseVersions)) { + if (is_array($enterpriseVersions) && array_key_exists(InfoCommand::AVAILABLE_VERSIONS, $enterpriseVersions)) { $enterpriseVersions = $this->sortVersions($enterpriseVersions); - if (isset($enterpriseVersions['available_versions'][0])) { - $maxVersion = $enterpriseVersions['available_versions'][0]; + if (isset($enterpriseVersions[InfoCommand::AVAILABLE_VERSIONS][0])) { + $maxVersion = $enterpriseVersions[InfoCommand::AVAILABLE_VERSIONS][0]; } $eeVersions = $this->filterEeVersions($currentCE, $enterpriseVersions, $maxVersion); } if (!empty($eeVersions)) { $result[] = [ - 'package' => 'magento/product-enterprise-edition', + 'package' => static::EDITION_ENTERPRISE, 'versions' => $eeVersions, ]; } @@ -140,7 +143,7 @@ class SystemPackage public function getAllowedB2BVersions($currentEE) { $result = []; - $versions = $this->fetchInfoVersions('magento/product-b2b-edition'); + $versions = $this->fetchInfoVersions(static::EDITION_B2B); $versionsPrepared = []; $maxVersion = ''; @@ -154,7 +157,7 @@ class SystemPackage if ($versionsPrepared) { $result[] = [ - 'package' => 'magento/product-b2b-edition', + 'package' => static::EDITION_B2B, 'versions' => $versionsPrepared, ]; } @@ -163,8 +166,7 @@ class SystemPackage } /** - * Fetching info command response to - * display all correct versions + * Fetching of info command response to display all correct versions * * @param string $command * @return array @@ -176,6 +178,9 @@ class SystemPackage $versions[InfoCommand::CURRENT_VERSION] = isset($versions[InfoCommand::CURRENT_VERSION]) ? $versions[InfoCommand::CURRENT_VERSION] : null; + $versions[InfoCommand::AVAILABLE_VERSIONS] = isset($versions[InfoCommand::AVAILABLE_VERSIONS]) + ? $versions[InfoCommand::AVAILABLE_VERSIONS] + : null; $versions[InfoCommand::AVAILABLE_VERSIONS] = array_unique( array_merge( (array)$versions[InfoCommand::CURRENT_VERSION], @@ -197,11 +202,11 @@ class SystemPackage $editionType = ''; $versions = []; - if ($systemPackageInfo['name'] == 'magento/product-community-edition') { + if ($systemPackageInfo['name'] == static::EDITION_COMMUNITY) { $editionType .= 'CE'; - } elseif ($systemPackageInfo['name'] == 'magento/product-enterprise-edition') { + } elseif ($systemPackageInfo['name'] == static::EDITION_ENTERPRISE) { $editionType .= 'EE'; - } elseif ($systemPackageInfo['name'] == 'magento/product-b2b-edition') { + } elseif ($systemPackageInfo['name'] == static::EDITION_B2B) { $editionType .= 'B2B'; } @@ -220,20 +225,18 @@ class SystemPackage } /** - * @param array $systemPackages * @return array * @throws \RuntimeException */ - public function getInstalledSystemPackages($systemPackages) + public function getInstalledSystemPackages() { - $systemPackages = []; $locker = $this->magentoComposerApplication->createComposer()->getLocker(); /** @var \Composer\Package\CompletePackage $package */ foreach ($locker->getLockedRepository()->getPackages() as $package) { $packageName = $package->getName(); if ($this->composerInfo->isSystemPackage($packageName)) { - if ($packageName == 'magento/product-community-edition') { + if ($packageName == static::EDITION_COMMUNITY) { if ($this->composerInfo->isPackageInComposerJson($packageName)) { $systemPackages[] = $packageName; } @@ -259,7 +262,7 @@ class SystemPackage */ public function sortVersions($enterpriseVersions) { - usort($enterpriseVersions['available_versions'], function ($versionOne, $versionTwo) { + usort($enterpriseVersions[InfoCommand::AVAILABLE_VERSIONS], function ($versionOne, $versionTwo) { if (version_compare($versionOne, $versionTwo, '==')) { return 0; } @@ -296,7 +299,7 @@ class SystemPackage usort($versions, function ($versionOne, $versionTwo) { if (version_compare($versionOne['id'], $versionTwo['id'], '==')) { - if ($versionOne['package'] === 'magento/product-community-edition') { + if ($versionOne['package'] === static::EDITION_COMMUNITY) { return 1; } return 0; @@ -316,11 +319,11 @@ class SystemPackage public function filterEeVersions($currentCE, $enterpriseVersions, $maxVersion) { $eeVersions = []; - foreach ($enterpriseVersions['available_versions'] as $version) { - $requires = $this->composerInfo->getPackageRequirements('magento/product-enterprise-edition', $version); - if (array_key_exists('magento/product-community-edition', $requires)) { + foreach ($enterpriseVersions[InfoCommand::AVAILABLE_VERSIONS] as $version) { + $requires = $this->composerInfo->getPackageRequirements(static::EDITION_ENTERPRISE, $version); + if (array_key_exists(static::EDITION_COMMUNITY, $requires)) { /** @var \Composer\Package\Link $ceRequire */ - $ceRequire = $requires['magento/product-community-edition']; + $ceRequire = $requires[static::EDITION_COMMUNITY]; if (version_compare( $ceRequire->getConstraint()->getPrettyString(), $currentCE, @@ -348,11 +351,11 @@ class SystemPackage public function filterB2bVersions($currentEE, $b2bVersions, $maxVersion) { $b2bVersionsPrepared = []; - foreach ($b2bVersions['available_versions'] as $version) { - $requires = $this->composerInfo->getPackageRequirements('magento/product-b2b-edition', $version); - if (array_key_exists('magento/product-enterprise-edition', $requires)) { + foreach ($b2bVersions[InfoCommand::AVAILABLE_VERSIONS] as $version) { + $requires = $this->composerInfo->getPackageRequirements(static::EDITION_B2B, $version); + if (array_key_exists(static::EDITION_ENTERPRISE, $requires)) { /** @var \Composer\Package\Link $eeRequire */ - $eeRequire = $requires['magento/product-enterprise-edition']; + $eeRequire = $requires[static::EDITION_ENTERPRISE]; if (version_compare( $eeRequire->getConstraint()->getPrettyString(), $currentEE, diff --git a/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php b/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php index bf9839495a8..b464af8519d 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/SystemPackageTest.php @@ -6,6 +6,7 @@ namespace Magento\Setup\Test\Unit\Model; +use Magento\Composer\InfoCommand; use Magento\Setup\Model\SystemPackage; class SystemPackageTest extends \PHPUnit_Framework_TestCase @@ -52,56 +53,56 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase [ 'id' => '1.2.0', 'name' => 'Version 1.2.0 EE (latest)', - 'package' => 'magento/product-enterprise-edition', + 'package' => SystemPackage::EDITION_ENTERPRISE, 'stable' => true, 'current' => false, ], [ 'id' => '1.2.0', 'name' => 'Version 1.2.0 CE (latest)', - 'package' => 'magento/product-community-edition', + 'package' => SystemPackage::EDITION_COMMUNITY, 'stable' => true, 'current' => false, ], [ 'id' => '1.1.0', 'name' => 'Version 1.1.0 EE', - 'package' => 'magento/product-enterprise-edition', + 'package' => SystemPackage::EDITION_ENTERPRISE, 'stable' => true, 'current' => false, ], [ 'id' => '1.1.0', 'name' => 'Version 1.1.0 CE', - 'package' => 'magento/product-community-edition', + 'package' => SystemPackage::EDITION_COMMUNITY, 'stable' => true, 'current' => false, ], [ 'id' => '1.1.0-RC1', 'name' => 'Version 1.1.0-RC1 EE (unstable version)', - 'package' => 'magento/product-enterprise-edition', + 'package' => SystemPackage::EDITION_ENTERPRISE, 'stable' => false, 'current' => false, ], [ 'id' => '1.1.0-RC1', 'name' => 'Version 1.1.0-RC1 CE (unstable version)', - 'package' => 'magento/product-community-edition', + 'package' => SystemPackage::EDITION_COMMUNITY, 'stable' => false, 'current' => false, ], [ 'id' => '1.0.0', 'name' => 'Version 1.0.0 EE', - 'package' => 'magento/product-enterprise-edition', + 'package' => SystemPackage::EDITION_ENTERPRISE, 'stable' => true, 'current' => true, ], [ 'id' => '1.0.0', 'name' => 'Version 1.0.0 CE', - 'package' => 'magento/product-community-edition', + 'package' => SystemPackage::EDITION_COMMUNITY, 'stable' => true, 'current' => true, ], @@ -147,9 +148,9 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase public function testGetPackageVersions() { $communityPackage = $this->getMock(\Composer\Package\Package::class, [], [], '', false); - $communityPackage->expects($this->once())->method('getName')->willReturn('magento/product-community-edition'); + $communityPackage->expects($this->once())->method('getName')->willReturn(SystemPackage::EDITION_COMMUNITY); $enterprisePackage = $this->getMock(\Composer\Package\Package::class, [], [], '', false); - $enterprisePackage->expects($this->once())->method('getName')->willReturn('magento/product-enterprise-edition'); + $enterprisePackage->expects($this->once())->method('getName')->willReturn(SystemPackage::EDITION_ENTERPRISE); $this->composerInformation->expects($this->any())->method('isSystemPackage')->willReturn(true); $this->composerInformation->expects($this->once())->method('isPackageInComposerJson')->willReturn(true); $this->repository @@ -180,54 +181,54 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase ->method('run') ->willReturnMap([ [ - 'magento/product-community-edition', + SystemPackage::EDITION_COMMUNITY, false, [ - 'name' => 'magento/product-community-edition', + 'name' => SystemPackage::EDITION_COMMUNITY, 'description' => 'eCommerce Platform for Growth (Enterprise Edition)', 'keywords' => '', 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', 'type' => 'metapackage', 'license' => 'OSL-3.0, AFL-3.0', 'source' => '[]', - 'names' => 'magento/product-community-edition', + 'names' => SystemPackage::EDITION_COMMUNITY, 'current_version' => '1.0.0', - 'available_versions' => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], + InfoCommand::AVAILABLE_VERSIONS => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], ], ], [ - 'magento/product-enterprise-edition', + SystemPackage::EDITION_ENTERPRISE, false, [ - 'name' => 'magento/product-enterprise-edition', + 'name' => SystemPackage::EDITION_ENTERPRISE, 'description' => 'eCommerce Platform for Growth (Enterprise Edition)', 'keywords' => '', 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', 'type' => 'metapackage', 'license' => 'OSL-3.0, AFL-3.0', 'source' => '[]', - 'names' => 'magento/product-enterprise-edition', + 'names' => SystemPackage::EDITION_ENTERPRISE, 'current_version' => '1.0.0', - 'available_versions' => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], + InfoCommand::AVAILABLE_VERSIONS => [1 => '1.2.0', 2 => '1.1.0', 3 => '1.1.0-RC1', 4 => '1.0.0'], 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], ], ], [ - 'magento/product-b2b-edition', + SystemPackage::EDITION_B2B, false, [ - 'name' => 'magento/product-b2b-edition', + 'name' => SystemPackage::EDITION_B2B, 'description' => 'eCommerce Platform for Growth (B2B Edition)', 'keywords' => '', 'versions' => '1.2.0, 1.1.0, 1.1.0-RC1, * 1.0.0', 'type' => 'metapackage', 'license' => 'OSL-3.0, AFL-3.0', 'source' => '[]', - 'names' => 'magento/product-b2b-edition', - 'available_versions' => [], + 'names' => SystemPackage::EDITION_B2B, + InfoCommand::AVAILABLE_VERSIONS => [], 'new_versions' => ['1.2.0', '1.1.0', '1.1.0-RC1'], ], ], @@ -273,8 +274,8 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $communityPackage = $this->getMock(\Composer\Package\Package::class, [], [], '', false); $enterprisePackage = $this->getMock(\Composer\Package\Package::class, [], [], '', false); - $communityPackage->expects($this->once())->method('getName')->willReturn('magento/product-community-edition'); - $enterprisePackage->expects($this->once())->method('getName')->willReturn('magento/product-enterprise-edition'); + $communityPackage->expects($this->once())->method('getName')->willReturn(SystemPackage::EDITION_COMMUNITY); + $enterprisePackage->expects($this->once())->method('getName')->willReturn(SystemPackage::EDITION_ENTERPRISE); $this->composerInformation->expects($this->any())->method('isSystemPackage')->willReturn(true); $this->composerInformation->expects($this->once())->method('isPackageInComposerJson')->willReturn(true); @@ -300,7 +301,7 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $this->infoCommand->expects($this->once()) ->method('run') - ->with('magento/product-community-edition') + ->with(SystemPackage::EDITION_COMMUNITY) ->willReturn(false); $this->systemPackage->getPackageVersions(); @@ -320,8 +321,8 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $this->systemPackage = new SystemPackage($this->composerAppFactory, $this->composerInformation); $this->infoCommand->expects($this->once()) ->method('run') - ->with('magento/product-enterprise-edition') - ->willReturn(['available_versions' => ['1.0.0', '1.0.1', '1.0.2']]); + ->with(SystemPackage::EDITION_ENTERPRISE) + ->willReturn([InfoCommand::AVAILABLE_VERSIONS => ['1.0.0', '1.0.1', '1.0.2']]); $require = $this->getMock(\Composer\Package\Link::class, [], [], '', false); $constraintMock = $this->getMock(\Composer\Semver\Constraint\Constraint::class, [], [], '', false); $constraintMock->expects($this->any())->method('getPrettyString') @@ -332,7 +333,7 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $this->composerInformation->expects($this->any()) ->method('getPackageRequirements') - ->willReturn(['magento/product-community-edition' => $require]); + ->willReturn([SystemPackage::EDITION_COMMUNITY => $require]); $this->assertEquals( $expectedResult, $this->systemPackage->getAllowedEnterpriseVersions($ceCurrentVersion) @@ -353,8 +354,8 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $this->systemPackage = new SystemPackage($this->composerAppFactory, $this->composerInformation); $this->infoCommand->expects($this->once()) ->method('run') - ->with('magento/product-b2b-edition') - ->willReturn(['available_versions' => ['1.0.0', '1.0.1', '1.0.2']]); + ->with(SystemPackage::EDITION_B2B) + ->willReturn([InfoCommand::AVAILABLE_VERSIONS => ['1.0.0', '1.0.1', '1.0.2']]); $require = $this->getMock(\Composer\Package\Link::class, [], [], '', false); $constraintMock = $this->getMock(\Composer\Semver\Constraint\Constraint::class, [], [], '', false); $constraintMock->expects($this->any())->method('getPrettyString') @@ -365,7 +366,7 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase $this->composerInformation->expects($this->any()) ->method('getPackageRequirements') - ->willReturn(['magento/product-enterprise-edition' => $require]); + ->willReturn([SystemPackage::EDITION_ENTERPRISE => $require]); $this->assertEquals( $expectedResult, $this->systemPackage->getAllowedB2BVersions($eeCurrentVersion) @@ -383,7 +384,7 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase '1.0.0', [ [ - 'package' => 'magento/product-enterprise-edition', + 'package' => SystemPackage::EDITION_ENTERPRISE, 'versions' => [ [ 'id' => '1.0.2', @@ -419,7 +420,7 @@ class SystemPackageTest extends \PHPUnit_Framework_TestCase '1.0.0', [ [ - 'package' => 'magento/product-b2b-edition', + 'package' => SystemPackage::EDITION_B2B, 'versions' => [ [ 'id' => '1.0.2', -- GitLab From 8bd8f70ffdfb52990b1984dff3fe3b67c46769dd Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 25 Aug 2016 09:33:47 -0500 Subject: [PATCH 670/838] MAGETWO-57237: Eliminate @escapeNotVerified in Review Module --- app/code/Magento/Review/view/frontend/templates/review.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml index a7459ca7e1b..c3f64511b15 100644 --- a/app/code/Magento/Review/view/frontend/templates/review.phtml +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -13,7 +13,7 @@ { "*": { "Magento_Review/js/process-reviews": { - "productReviewUrl": "<?php echo $block->escapeUrl($block->getProductReviewUrl()); ?>" + "productReviewUrl": "<?php echo $block->escapeJs($block->escapeUrl($block->getProductReviewUrl())); ?>" } } } -- GitLab From 595dcdac476e6bd28e008708f28af53bfe37e6bd Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Thu, 25 Aug 2016 17:37:07 +0300 Subject: [PATCH 671/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- setup/src/Magento/Setup/Model/SystemPackage.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/src/Magento/Setup/Model/SystemPackage.php b/setup/src/Magento/Setup/Model/SystemPackage.php index 2b8bcf8166c..5aa048e27c0 100755 --- a/setup/src/Magento/Setup/Model/SystemPackage.php +++ b/setup/src/Magento/Setup/Model/SystemPackage.php @@ -31,6 +31,9 @@ class SystemPackage */ private $composerInfo; + /**#@+ + * Constants for different Magento editions + */ const EDITION_COMMUNITY = 'magento/product-community-edition'; const EDITION_ENTERPRISE = 'magento/product-enterprise-edition'; const EDITION_B2B = 'magento/product-b2b-edition'; -- GitLab From 79b4badcc96a4d19f43d5bcb45431f21d47e1e59 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 25 Aug 2016 10:39:18 -0500 Subject: [PATCH 672/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../Block/Account/AuthenticationPopupTest.php | 53 +++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php b/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php index 05f56d25702..f0ec5ec9148 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php @@ -14,6 +14,9 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase { /** @var AuthenticationPopup */ @@ -53,6 +56,24 @@ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase $this->contextMock->expects($this->once()) ->method('getUrlBuilder') ->willReturn($this->urlBuilderMock); + $escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) + ->disableOriginalConstructor() + ->getMock(); + $escaperMock->method('escapeHtml') + ->willReturnCallback( + function ($string) { + return 'escapeHtml' . $string; + } + ); + $escaperMock->method('escapeUrl') + ->willReturnCallback( + function ($string) { + return 'escapeUrl' . $string; + } + ); + $this->contextMock->expects($this->once()) + ->method('getEscaper') + ->willReturn($escaperMock); $this->model = new AuthenticationPopup( $this->contextMock @@ -110,10 +131,10 @@ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase 'reg', 'forgot', [ - 'autocomplete' => 'off', - 'customerRegisterUrl' => 'reg', - 'customerForgotPasswordUrl' => 'forgot', - 'baseUrl' => 'base', + 'autocomplete' => 'escapeHtmloff', + 'customerRegisterUrl' => 'escapeUrlreg', + 'customerForgotPasswordUrl' => 'escapeUrlforgot', + 'baseUrl' => 'escapeUrlbase', ], ], [ @@ -122,10 +143,10 @@ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase 'reg', 'forgot', [ - 'autocomplete' => 'on', - 'customerRegisterUrl' => 'reg', - 'customerForgotPasswordUrl' => 'forgot', - 'baseUrl' => '', + 'autocomplete' => 'escapeHtmlon', + 'customerRegisterUrl' => 'escapeUrlreg', + 'customerForgotPasswordUrl' => 'escapeUrlforgot', + 'baseUrl' => 'escapeUrl', ], ], [ @@ -134,10 +155,10 @@ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase '', 'forgot', [ - 'autocomplete' => 'off', - 'customerRegisterUrl' => '', - 'customerForgotPasswordUrl' => 'forgot', - 'baseUrl' => 'base', + 'autocomplete' => 'escapeHtmloff', + 'customerRegisterUrl' => 'escapeUrl', + 'customerForgotPasswordUrl' => 'escapeUrlforgot', + 'baseUrl' => 'escapeUrlbase', ], ], [ @@ -146,10 +167,10 @@ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase 'reg', '', [ - 'autocomplete' => 'on', - 'customerRegisterUrl' => 'reg', - 'customerForgotPasswordUrl' => '', - 'baseUrl' => 'base', + 'autocomplete' => 'escapeHtmlon', + 'customerRegisterUrl' => 'escapeUrlreg', + 'customerForgotPasswordUrl' => 'escapeUrl', + 'baseUrl' => 'escapeUrlbase', ], ], ]; -- GitLab From 3464d61ddb36fbfa1a162b8186af1fa41ca9576e Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 25 Aug 2016 10:39:27 -0500 Subject: [PATCH 673/838] MAGETWO-57232: Eliminate @escapeNotVerified in Wishlist Module --- .../Test/Unit/Block/Item/ConfigureTest.php | 68 +++++++++++-------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/app/code/Magento/Wishlist/Test/Unit/Block/Item/ConfigureTest.php b/app/code/Magento/Wishlist/Test/Unit/Block/Item/ConfigureTest.php index eb383631106..7e12552f6c4 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Block/Item/ConfigureTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Block/Item/ConfigureTest.php @@ -12,39 +12,51 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Wishlist\Block\Item\Configure */ - protected $_model; + protected $model; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_mockRegistry; + protected $registryMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_mockContext; + protected $contextMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_mockWishlistData; + protected $wishlistDataMock; protected function setUp() { - $this->_mockWishlistData = $this->getMockBuilder( + $this->wishlistDataMock = $this->getMockBuilder( \Magento\Wishlist\Helper\Data::class )->disableOriginalConstructor()->getMock(); - $this->_mockContext = $this->getMockBuilder( + $this->contextMock = $this->getMockBuilder( \Magento\Framework\View\Element\Template\Context::class )->disableOriginalConstructor()->getMock(); - $this->_mockRegistry = $this->getMockBuilder(\Magento\Framework\Registry::class) + $this->registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class) ->disableOriginalConstructor() ->getMock(); - - $this->_model = new \Magento\Wishlist\Block\Item\Configure( - $this->_mockContext, - $this->_mockWishlistData, - $this->_mockRegistry + $escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) + ->disableOriginalConstructor() + ->getMock(); + $escaperMock->method('escapeHtml') + ->willReturnCallback( + function ($string) { + return 'escapeHtml' . $string; + } + ); + $this->contextMock->expects($this->once()) + ->method('getEscaper') + ->willReturn($escaperMock); + + $this->model = new \Magento\Wishlist\Block\Item\Configure( + $this->contextMock, + $this->wishlistDataMock, + $this->registryMock ); } @@ -55,18 +67,18 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase \Magento\Catalog\Model\Product::class )->disableOriginalConstructor()->getMock(); $product->expects($this->once())->method('getTypeId')->willReturn($typeId); - $this->_mockRegistry->expects($this->once()) + $this->registryMock->expects($this->once()) ->method('registry') ->with($this->equalTo('product')) ->willReturn($product); - $this->assertEquals(['productType' => $typeId], $this->_model->getWishlistOptions()); + $this->assertEquals(['productType' => 'escapeHtml' . $typeId], $this->model->getWishlistOptions()); } public function testGetProduct() { $product = 'some test product'; - $this->_mockRegistry->expects( + $this->registryMock->expects( $this->once() )->method( 'registry' @@ -76,7 +88,7 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase $product ); - $this->assertEquals($product, $this->_model->getProduct()); + $this->assertEquals($product, $this->model->getProduct()); } public function testSetLayout() @@ -109,12 +121,12 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase false ); - $this->_mockRegistry->expects($this->exactly(2)) + $this->registryMock->expects($this->exactly(2)) ->method('registry') ->with('wishlist_item') ->willReturn($itemMock); - $this->_mockWishlistData->expects($this->once()) + $this->wishlistDataMock->expects($this->once()) ->method('getAddToCartUrl') ->with($itemMock) ->willReturn('some_url'); @@ -123,8 +135,8 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase ->method('setCustomAddToCartUrl') ->with('some_url'); - $this->assertEquals($this->_model, $this->_model->setLayout($layoutMock)); - $this->assertEquals($layoutMock, $this->_model->getLayout()); + $this->assertEquals($this->model, $this->model->setLayout($layoutMock)); + $this->assertEquals($layoutMock, $this->model->getLayout()); } public function testSetLayoutWithNoItem() @@ -149,19 +161,19 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase ->with('product.info') ->willReturn($blockMock); - $this->_mockRegistry->expects($this->exactly(1)) + $this->registryMock->expects($this->exactly(1)) ->method('registry') ->with('wishlist_item') ->willReturn(null); - $this->_mockWishlistData->expects($this->never()) + $this->wishlistDataMock->expects($this->never()) ->method('getAddToCartUrl'); $blockMock->expects($this->never()) ->method('setCustomAddToCartUrl'); - $this->assertEquals($this->_model, $this->_model->setLayout($layoutMock)); - $this->assertEquals($layoutMock, $this->_model->getLayout()); + $this->assertEquals($this->model, $this->model->setLayout($layoutMock)); + $this->assertEquals($layoutMock, $this->model->getLayout()); } public function testSetLayoutWithNoBlockAndItem() @@ -179,13 +191,13 @@ class ConfigureTest extends \PHPUnit_Framework_TestCase ->with('product.info') ->willReturn(null); - $this->_mockRegistry->expects($this->never()) + $this->registryMock->expects($this->never()) ->method('registry'); - $this->_mockWishlistData->expects($this->never()) + $this->wishlistDataMock->expects($this->never()) ->method('getAddToCartUrl'); - $this->assertEquals($this->_model, $this->_model->setLayout($layoutMock)); - $this->assertEquals($layoutMock, $this->_model->getLayout()); + $this->assertEquals($this->model, $this->model->setLayout($layoutMock)); + $this->assertEquals($layoutMock, $this->model->getLayout()); } } -- GitLab From e9307e10f5260cf83a4781297c6c2683214dd086 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Thu, 25 Aug 2016 18:45:49 +0300 Subject: [PATCH 674/838] MAGETWO-55908: Prepare PR --- .../Product/Form/Modifier/AdvancedPricing.php | 28 +++++++ .../Rule/CustomerGroupsOptionsProvider.php | 48 ++++++++++++ .../CustomerGroupsOptionsProviderTest.php | 73 +++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php create mode 100644 app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 3905905e7e7..1f85d81a5df 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -152,6 +152,34 @@ class AdvancedPricing extends AbstractModifier return $data; } + /** + * Prepare price fields + * + * Add currency symbol and validation + * + * @param string $fieldCode + * @return $this + */ + protected function preparePriceFields($fieldCode) + { + $pricePath = $this->arrayManager->findPath($fieldCode, $this->meta, null, 'children'); + + if ($pricePath) { + $this->meta = $this->arrayManager->set( + $pricePath . '/arguments/data/config/addbefore', + $this->meta, + $this->getStore()->getBaseCurrency()->getCurrencySymbol() + ); + $this->meta = $this->arrayManager->merge( + $pricePath . '/arguments/data/config', + $this->meta, + ['validation' => ['validate-zero-or-greater' => true]] + ); + } + + return $this; + } + /** * Customize tier price field * diff --git a/app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php b/app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php new file mode 100644 index 00000000000..ebc0747d83a --- /dev/null +++ b/app/code/Magento/CatalogRule/Model/Rule/CustomerGroupsOptionsProvider.php @@ -0,0 +1,48 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogRule\Model\Rule; + +class CustomerGroupsOptionsProvider implements \Magento\Framework\Data\OptionSourceInterface +{ + /** + * @var \Magento\Customer\Api\GroupRepositoryInterface + */ + private $groupRepository; + + /** + * @var \Magento\Framework\Api\SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var \Magento\Framework\Convert\DataObject + */ + private $objectConverter; + + /** + * @param \Magento\Customer\Api\GroupRepositoryInterface $groupRepository + * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder + * @param \Magento\Framework\Convert\DataObject $objectConverter + */ + public function __construct( + \Magento\Customer\Api\GroupRepositoryInterface $groupRepository, + \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, + \Magento\Framework\Convert\DataObject $objectConverter + ) { + $this->groupRepository = $groupRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->objectConverter = $objectConverter; + } + + /** + * @return array + */ + public function toOptionArray() + { + $customerGroups = $this->groupRepository->getList($this->searchCriteriaBuilder->create())->getItems(); + return $this->objectConverter->toOptionArray($customerGroups, 'id', 'code'); + } +} diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php new file mode 100644 index 00000000000..464857949a4 --- /dev/null +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/CustomerGroupsOptionsProviderTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogRule\Test\Unit\Model\Rule; + +class CustomerGroupsOptionsProviderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider + */ + private $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $groupRepositoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $searchCriteriaBuilderMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $objectConverterMock; + + protected function setup() + { + $this->groupRepositoryMock = $this->getMock(\Magento\Customer\Api\GroupRepositoryInterface::class); + $this->searchCriteriaBuilderMock = $this->getMock( + \Magento\Framework\Api\SearchCriteriaBuilder::class, + [], + [], + '', + false + ); + $this->objectConverterMock = $this->getMock(\Magento\Framework\Convert\DataObject::class, [], [], '', false); + $this->model = new \Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider( + $this->groupRepositoryMock, + $this->searchCriteriaBuilderMock, + $this->objectConverterMock + ); + } + + public function testToOptionArray() + { + $customerGroups = ['group1', 'group2']; + + $options = [ + ['label' => 'label', 'value' => 'value'] + ]; + + $searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false); + $searchResultMock = $this->getMock(\Magento\Customer\Api\Data\GroupSearchResultsInterface::class); + $this->searchCriteriaBuilderMock->expects($this->once())->method('create')->willReturn($searchCriteriaMock); + + $this->groupRepositoryMock->expects($this->once()) + ->method('getList') + ->with($searchCriteriaMock) + ->willReturn($searchResultMock); + + $searchResultMock->expects($this->once())->method('getItems')->willReturn($customerGroups); + $this->objectConverterMock->expects($this->once()) + ->method('toOptionArray') + ->with($customerGroups, 'id', 'code') + ->willReturn($options); + + $this->assertEquals($options, $this->model->toOptionArray()); + } +} -- GitLab From e3a2cfd52ceac437161f6a51df1f221cff85d2f7 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 25 Aug 2016 11:53:37 -0500 Subject: [PATCH 675/838] MAGETWO-55870: Eliminate @escapeNotVerified in Directory module - Eliminated all instances. - Removed directory and security modules from whitelist for notverified static test. --- app/code/Magento/Directory/Block/Currency.php | 2 +- .../templates/js/optional_zip_countries.phtml | 6 ++--- .../view/frontend/templates/currency.phtml | 22 +++++++++---------- .../frontend/templates/currency/switch.phtml | 6 +++-- .../_files/whitelist/exempt_modules/ce.php | 2 -- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Directory/Block/Currency.php b/app/code/Magento/Directory/Block/Currency.php index c8c89d2b163..cd3064ac2cb 100644 --- a/app/code/Magento/Directory/Block/Currency.php +++ b/app/code/Magento/Directory/Block/Currency.php @@ -111,7 +111,7 @@ class Currency extends \Magento\Framework\View\Element\Template */ public function getSwitchCurrencyPostData($code) { - return $this->_postDataHelper->getPostData($this->getSwitchUrl(), ['currency' => $code]); + return $this->_postDataHelper->getPostData($this->escapeUrl($this->getSwitchUrl()), ['currency' => $code]); } /** diff --git a/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml b/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml index f7d99f4a007..4b849d6abf6 100644 --- a/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml +++ b/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml @@ -5,14 +5,12 @@ */ // @codingStandardsIgnoreFile -?> - -<?php /** * JS block for including Countries with Optional Zip * * @see \Magento\Backend\Block\Template */ + ?> <script> require([ @@ -21,7 +19,7 @@ require([ ], function(){ //<![CDATA[ -optionalZipCountries = <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?>; +optionalZipCountries = <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?>; function onAddressCountryChanged (countryElement) { var zipElementId = countryElement.id.replace(/country_id/, 'postcode'); diff --git a/app/code/Magento/Directory/view/frontend/templates/currency.phtml b/app/code/Magento/Directory/view/frontend/templates/currency.phtml index 9f575624008..e5e4b0fa9f4 100644 --- a/app/code/Magento/Directory/view/frontend/templates/currency.phtml +++ b/app/code/Magento/Directory/view/frontend/templates/currency.phtml @@ -5,38 +5,36 @@ */ // @codingStandardsIgnoreFile - -?> -<?php /** * Currency switcher * - * @see \Magento\Directory\Block\Currency + * @var \Magento\Directory\Block\Currency $block */ + ?> <?php if ($block->getCurrencyCount() > 1): ?> <?php $currencies = $block->getCurrencies(); ?> <?php $currentCurrencyCode = $block->getCurrentCurrencyCode(); ?> -<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> -<div class="switcher currency switcher-currency" id="switcher-currency<?php /* @escapeNotVerified */ echo $id?>"> - <strong class="label switcher-label"><span><?php /* @escapeNotVerified */ echo __('Currency') ?></span></strong> +<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : '' ?> +<div class="switcher currency switcher-currency" id="switcher-currency<?php echo $block->escapeHtmlAttr($id) ?>"> + <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Currency')) ?></span></strong> <div class="actions dropdown options switcher-options"> - <div class="action toggle switcher-trigger" id="switcher-currency-trigger<?php /* @escapeNotVerified */ echo $id?>"> + <div class="action toggle switcher-trigger" id="switcher-currency-trigger<?php echo $block->escapeHtmlAttr($id) ?>"> <strong class="language-<?php echo $block->escapeHtml($block->getCurrentCurrencyCode()) ?>"> <span><?php echo $block->escapeHtml($currentCurrencyCode) ?> - <?php echo @$block->escapeHtml($currencies[$currentCurrencyCode]) ?></span> </strong> </div> <ul class="dropdown switcher-dropdown" data-mage-init='{"dropdownDialog":{ - "appendTo":"#switcher-currency<?php /* @escapeNotVerified */ echo $id?> > .options", - "triggerTarget":"#switcher-currency-trigger<?php /* @escapeNotVerified */ echo $id?>", + "appendTo":"#switcher-currency<?php echo $block->escapeJs($id) ?> > .options", + "triggerTarget":"#switcher-currency-trigger<?php echo $block->escapeJs($id) ?>", "closeOnMouseLeave": false, "triggerClass":"active", "parentClass":"active", "buttons":null}}'> <?php foreach ($currencies as $_code => $_name): ?> <?php if ($_code != $currentCurrencyCode): ?> - <li class="currency-<?php /* @escapeNotVerified */ echo $_code ?> switcher-option"> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getSwitchCurrencyPostData($_code); ?>'><?php /* @escapeNotVerified */ echo $_code ?> - <?php /* @escapeNotVerified */ echo $_name ?></a> + <li class="currency-<?php echo $block->escapeHtmlAttr($_code) ?> switcher-option"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getSwitchCurrencyPostData($_code); ?>'><?php echo $block->escapeHtml($_code) ?> - <?php echo $block->escapeHtml($_name) ?></a> </li> <?php endif; ?> <?php endforeach; ?> diff --git a/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml b/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml index 92c397fb00b..f86b1c0f1fa 100644 --- a/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml +++ b/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Framework\View\Element\Template $block */ + ?> -<p><?php /* @escapeNotVerified */ echo __('Your current currency is: %1.', $currency->getCode()) ?></p> -<p><a href="<?php /* @escapeNotVerified */ echo $block->getBaseUrl(); ?>" class="action continue"><span><?php /* @escapeNotVerified */ echo __('Continue') ?></span></a></p> +<p><?php echo $block->escapeHtml(__('Your current currency is: %1.', $currency->getCode())) ?></p> +<p><a href="<?php echo $block->escapeUrl($block->getBaseUrl()); ?>" class="action continue"><span><?php echo $block->escapeHtml(__('Continue')) ?></span></a></p> diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php index 077bc4138d1..18491844df0 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -20,7 +20,6 @@ return [ 'Magento_Config', 'Magento_ConfigurableProduct', 'Magento_CurrencySymbol', - 'Magento_Directory', 'Magento_Downloadable', 'Magento_Email', 'Magento_GiftMessage', @@ -40,7 +39,6 @@ return [ 'Magento_Reports', 'Magento_Sales', 'Magento_Search', - 'Magento_Security', 'Magento_Shipping', 'Magento_Store', 'Magento_Swagger', -- GitLab From 383b20036568ebc2072246e428437a9806c596a2 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Thu, 25 Aug 2016 14:53:34 -0500 Subject: [PATCH 676/838] MAGETWO-57237: Eliminate @escapeNotVerified in Review Module - fixed code style - fixed XSS test to allow whitespaces in the end of the line w/o ";" --- .../Magento/Review/view/frontend/templates/customer/list.phtml | 2 +- .../Magento/TestFramework/Utility/XssOutputValidator.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml index 7d19e34e368..69d5ac0fa7d 100644 --- a/app/code/Magento/Review/view/frontend/templates/customer/list.phtml +++ b/app/code/Magento/Review/view/frontend/templates/customer/list.phtml @@ -34,7 +34,7 @@ <?php if ($_review->getSum()): ?> <div class="rating-summary"> <span class="label"><span><?php echo $block->escapeHtml(__('Rating')) ?>:</span></span> - <div class="rating-result" title="<?php echo /* @noEscape */ ((int)$_review->getSum() / (int)$_review->getCount()) ?>%"> + <div class="rating-result" title="<?php /* @noEscape */ echo ((int)$_review->getSum() / (int)$_review->getCount()) ?>%"> <span style="width:<?php /* @noEscape */ echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%;"><span><?php /* @noEscape */ echo((int)$_review->getSum() / (int)$_review->getCount()) ?>%</span></span> </div> </div> diff --git a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php index 48acb58019a..329142659db 100644 --- a/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php +++ b/dev/tests/static/framework/Magento/TestFramework/Utility/XssOutputValidator.php @@ -160,7 +160,7 @@ class XssOutputValidator private function prepareEchoCommand($command) { $command = preg_replace('/<[?]=(.*?)[?]>/sim', '\1', $command); - return ltrim(explode(';', $command)[0], 'echo'); + return trim(ltrim(explode(';', $command)[0], 'echo')); } /** -- GitLab From cbbbf6f8647226c1fc80e5cfc0dc2855c73f6aef Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 25 Aug 2016 17:59:43 -0500 Subject: [PATCH 677/838] MAGETWO-57270: Create unit test to cover change to escapeHtml - Added more cases for testing escapeHtml. --- .../Framework/Test/Unit/EscaperTest.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index c3581df8121..5c68e4a4667 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -46,6 +46,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase */ public function escapeHtmlDataProvider() { + $zendEscaper = new \Magento\Framework\ZendEscaper(); return [ 'array data' => [ 'data' => ['one', '<two>three</two>'], @@ -58,6 +59,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase null, ], 'string data no conversion' => ['data' => 'one', 'expected' => 'one'], + 'string data with special chars' => ['data' => '&<>"\'', 'expected' => '&<>"''], + 'string with using escapeJs' => ['data' => '<script>' . $zendEscaper->escapeJs('var bar = "&<>\'";') . '</script>', 'expected' => '<script>var\x20bar\x20\x3D\x20\x22\x26\x3C\x3E\x27\x22\x3B</script>', 'allowedTags' => ['script']], 'string data with allowed tags' => [ 'data' => '<span><b>some text in tags</b></span>', 'expected' => '<span><b>some text in tags</b></span>', @@ -78,6 +81,21 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', 'allowedTags' => ['a'], ], + 'string data with allowed tags with attributes 4' => [ + 'data' => 'Only <span id=\'<span>\'><b>2</b></span> in stock', + 'expected' => 'Only <span id="<span>"><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + 'string data with allowed tags with attributes 5' => [ + 'data' => 'Only <span type=\'1\'><b>2</b></span> in stock', + 'expected' => 'Only <span type='1'><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + 'string data with allowed tags with attributes 6' => [ + 'data' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', + 'expected' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], 'string data with allowed tags with attributes and not allowed tags' => [ 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', @@ -88,6 +106,11 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'expected' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a class="some-class" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', 'allowedTags' => ['a', 'span'], ], + 'string data with allowed tags and html comment' => [ + 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'allowedTags' => ['span', 'b'], + ], ]; } -- GitLab From 20b39aacac29cb4e7a633e3c1a0d200dab288ea9 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 25 Aug 2016 18:43:35 -0500 Subject: [PATCH 678/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 65 +++++++++++----------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index c3ad8ab90d6..4d34b23b467 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -67,56 +67,59 @@ class Escaper $string ); - $newTagReplacements = []; foreach ($tagReplacements as $tagReplacementKey => $tagReplacement) { $isClosing = substr($tagReplacement, 0, 2) == '</'; $isSelfClosing = substr($tagReplacement, -2) == '/>'; + preg_match('/<\/?(\w+)(\s|>)/', $tagReplacement, $matches); + $tagName = $matches[1]; + + if (!in_array($tagName, $allowedTags)) { + $tagReplacements[$tagReplacementKey] = ''; + continue; + } + if (!$isClosing) { - $tagReplacement = str_replace(['&', '<', '>'], ['&', '<', '>'], $tagReplacement); $length = strlen($tagReplacement); - $end = substr($tagReplacement, -2); - set_error_handler( function($errorNumber, $errorString, $errorFile, $errorLine) { throw new \Exception($errorString, $errorNumber); } ); try { - $tag = new \SimpleXMLElement( - $end == '/>' ? $tagReplacement : (substr($tagReplacement, 0, $length-1) . ' />') + $tagReplacement = substr($tagReplacement, 1, $length - 2); + $tagReplacement = str_replace( + ['&', '<', '>'], + ['&', '<', '>'], + $tagReplacement ); + + $dom = new \DOMDocument(); + $dom->loadHTML('<' . $tagReplacement . '>'); } catch (\Exception $e) { - $newTagReplacements[$tagReplacementKey] = ''; + $tagReplacements[$tagReplacementKey] = ''; restore_error_handler(); continue; } restore_error_handler(); - $tagName = $tag->getName(); - } else { - $tagName = trim($tagReplacement, '<>/'); - } - - if (!in_array($tagName, $allowedTags)) { - $newTagReplacements[$tagReplacementKey] = ''; - continue; - } - - $attributes = []; - if (!$isClosing && $tag->attributes()) { - foreach ($tag->attributes() as $attributeName => $attributeValue) { - if (in_array($attributeName, $this->allowedAttributes)) { - $attributes[] = $attributeName . '="' - . $this->escapeAttributeValue( - $attributeName, - str_replace(['&', '<', '>'], ['&', '<', '>'], $attributeValue) - ) - . '"'; + $element = $dom->getElementsByTagName($tagName)[0]; + $attributes = []; + if ($element->attributes) { + foreach($element->attributes as $attribute) { + if (in_array($attribute->name, $this->allowedAttributes)) { + $attributes[] = $attribute->name . '="' + . $this->escapeAttributeValue( + $attribute->name, + $attribute->value + ) + . '"'; + } } + $tagReplacements[$tagReplacementKey] = '<' . $tagName . ' ' . implode(' ', $attributes) + . ($isSelfClosing ? '/>' : '>'); } - $newTagReplacements[$tagReplacementKey] = '<' . $tagName . ' ' . implode(' ', $attributes) . '>'; } else { - $newTagReplacements[$tagReplacementKey] = $isSelfClosing + $tagReplacements[$tagReplacementKey] = $isSelfClosing ? '<' . $tagName . ' />' : '</' . $tagName . '>'; } } @@ -125,8 +128,8 @@ class Escaper $string = preg_replace_callback( '/-=replacement-(\d)=-/si', - function($matches) use ($newTagReplacements) { - return $newTagReplacements[$matches[1]]; + function($matches) use ($tagReplacements) { + return $tagReplacements[$matches[1]]; }, $string ); -- GitLab From c88538a19e439a70ac1fbf431504fcb3fa7708b0 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 25 Aug 2016 20:45:29 -0500 Subject: [PATCH 679/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 117 ++++++------------ .../Framework/Test/Unit/EscaperTest.php | 27 ++-- 2 files changed, 54 insertions(+), 90 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 4d34b23b467..9ee3b0aa9d4 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -55,86 +55,51 @@ class Escaper */ private function escapeHtmlTagsAndAttributes($string, $allowedTags) { - $tagReplacements = []; - - $string = preg_replace_callback( - '/<.+?>/si', - function ($matches) use (&$tagReplacements) { - $result = '-=replacement-' . count($tagReplacements) . '=-'; - $tagReplacements[] = $matches[0]; - return $result; - }, - $string - ); - - foreach ($tagReplacements as $tagReplacementKey => $tagReplacement) { - $isClosing = substr($tagReplacement, 0, 2) == '</'; - $isSelfClosing = substr($tagReplacement, -2) == '/>'; - - preg_match('/<\/?(\w+)(\s|>)/', $tagReplacement, $matches); - $tagName = $matches[1]; - - if (!in_array($tagName, $allowedTags)) { - $tagReplacements[$tagReplacementKey] = ''; - continue; + $wrapperElementId = uniqid(); + $dom = new \DOMDocument('1.0', 'UTF-8'); + set_error_handler( + function($errorNumber, $errorString, $errorFile, $errorLine) { + throw new \Exception($errorString, $errorNumber); } - - if (!$isClosing) { - $length = strlen($tagReplacement); - set_error_handler( - function($errorNumber, $errorString, $errorFile, $errorLine) { - throw new \Exception($errorString, $errorNumber); - } - ); - try { - $tagReplacement = substr($tagReplacement, 1, $length - 2); - $tagReplacement = str_replace( - ['&', '<', '>'], - ['&', '<', '>'], - $tagReplacement - ); - - $dom = new \DOMDocument(); - $dom->loadHTML('<' . $tagReplacement . '>'); - } catch (\Exception $e) { - $tagReplacements[$tagReplacementKey] = ''; - restore_error_handler(); - continue; - } - restore_error_handler(); - $element = $dom->getElementsByTagName($tagName)[0]; - $attributes = []; - if ($element->attributes) { - foreach($element->attributes as $attribute) { - if (in_array($attribute->name, $this->allowedAttributes)) { - $attributes[] = $attribute->name . '="' - . $this->escapeAttributeValue( - $attribute->name, - $attribute->value - ) - . '"'; - } - } - $tagReplacements[$tagReplacementKey] = '<' . $tagName . ' ' . implode(' ', $attributes) - . ($isSelfClosing ? '/>' : '>'); - } - } else { - $tagReplacements[$tagReplacementKey] = $isSelfClosing - ? '<' . $tagName . ' />' : '</' . $tagName . '>'; + ); + try { + $dom->loadHTML('<html><body id="' . $wrapperElementId . '">' . $string . '</body></html>'); + } catch (\Exception $e) { + restore_error_handler(); + return ''; + } + restore_error_handler(); + + $xpath = new \DOMXPath($dom); + $nodes = $xpath->query('//node()[name() != \'' + . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) . '\']'); + foreach ($nodes as $node) { + if ($node->nodeName != '#text') { + $node->parentNode->replaceChild($dom->createTextNode($node->textContent), $node); } } - - $string = $this->escapeHtml($string); - - $string = preg_replace_callback( - '/-=replacement-(\d)=-/si', - function($matches) use ($tagReplacements) { - return $tagReplacements[$matches[1]]; - }, - $string + $nodes = $xpath->query('//@*[name() != \'' . implode('\' and name() != \'', $this->allowedAttributes) . '\']'); + foreach ($nodes as $node) { + $node->parentNode->removeAttribute($node->nodeName); + } + $nodes = $xpath->query('//text()'); + foreach ($nodes as $node) { + $node->textContent = $this->escapeHtml($node->textContent); + } + $nodes = $xpath->query('//@*'); + foreach ($nodes as $node) { + $value = $this->escapeAttributeValue( + $node->nodeName, + $node->parentNode->getAttribute($node->nodeName) + ); + $node->parentNode->setAttribute($node->nodeName, $value); + } + $result = mb_convert_encoding( + str_replace("\n", '', $dom->saveHTML($dom->getElementById($wrapperElementId))), + 'UTF-8', + 'HTML-ENTITIES' ); - - return $string; + return mb_substr($result, 25, strlen($result) - 32); } /** diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 5c68e4a4667..a0b8b238a1e 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -60,7 +60,6 @@ class EscaperTest extends \PHPUnit_Framework_TestCase ], 'string data no conversion' => ['data' => 'one', 'expected' => 'one'], 'string data with special chars' => ['data' => '&<>"\'', 'expected' => '&<>"''], - 'string with using escapeJs' => ['data' => '<script>' . $zendEscaper->escapeJs('var bar = "&<>\'";') . '</script>', 'expected' => '<script>var\x20bar\x20\x3D\x20\x22\x26\x3C\x3E\x27\x22\x3B</script>', 'allowedTags' => ['script']], 'string data with allowed tags' => [ 'data' => '<span><b>some text in tags</b></span>', 'expected' => '<span><b>some text in tags</b></span>', @@ -88,29 +87,29 @@ class EscaperTest extends \PHPUnit_Framework_TestCase ], 'string data with allowed tags with attributes 5' => [ 'data' => 'Only <span type=\'1\'><b>2</b></span> in stock', - 'expected' => 'Only <span type='1'><b>2</b></span> in stock', - 'allowedTags' => ['span', 'b'], - ], - 'string data with allowed tags with attributes 6' => [ - 'data' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', - 'expected' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', + 'expected' => 'Only <span><b>2</b></span> in stock', 'allowedTags' => ['span', 'b'], ], +// 'string data with allowed tags with attributes 6' => [ +// 'data' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', +// 'expected' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', +// 'allowedTags' => ['span', 'b'], +// ], 'string data with allowed tags with attributes and not allowed tags' => [ 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', - 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> or <a href="%2">create an account</a>', 'allowedTags' => ['a'], ], 'string data with allowed tags with attributes and not allowed tags 2' => [ 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a class="some-class" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', - 'expected' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a class="some-class" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', + 'expected' => 'Some test <span>text in span tag</span> text in strong tag <a class="some-class" href="http://domain.com/">Click here</a>alert(1)', 'allowedTags' => ['a', 'span'], ], - 'string data with allowed tags and html comment' => [ - 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', - 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', - 'allowedTags' => ['span', 'b'], - ], +// 'string data with allowed tags and html comment' => [ +// 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', +// 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', +// 'allowedTags' => ['span', 'b'], +// ], ]; } -- GitLab From 494cdbc46de764520cf15f7f1e9a2b0bcb71f5c9 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Fri, 26 Aug 2016 11:35:28 +0300 Subject: [PATCH 680/838] MAGETWO-55345: Grunt uses actual theme's list --- Gruntfile.js.sample | 8 ++- dev/tools/grunt/tools/files-router.js | 71 ++++++++++++++++++--------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/Gruntfile.js.sample b/Gruntfile.js.sample index 1e9c191ba11..ae7fca38bc6 100644 --- a/Gruntfile.js.sample +++ b/Gruntfile.js.sample @@ -11,9 +11,13 @@ module.exports = function (grunt) { var _ = require('underscore'), path = require('path'), - themes = require('./dev/tools/grunt/tools/files-router').get('themes'), + filesRouter = require('./dev/tools/grunt/tools/files-router'), configDir = './dev/tools/grunt/configs', - tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'); + tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'), + themes; + + filesRouter.set('themes', 'dev/tools/grunt/configs/themes') + themes = filesRouter.get('themes') tasks = _.map(tasks, function(task){ return task.replace('.js', '') }); tasks.push('time-grunt'); diff --git a/dev/tools/grunt/tools/files-router.js b/dev/tools/grunt/tools/files-router.js index c120af31df6..2bf6f9d8cc2 100644 --- a/dev/tools/grunt/tools/files-router.js +++ b/dev/tools/grunt/tools/files-router.js @@ -5,22 +5,47 @@ 'use strict'; -module.exports = { - defaultConfig: { - 'themes': 'dev/tools/grunt/configs/themes' +var defaultConfig = {}, + + /** + * Generates full path to file. + * + * @param {String} path - relative path to file. + * + * @returns {String} Full path to file + */ + getFullPath = function (path) { + return process.cwd() + '/' + path; + }, + + /** + * Returns file. + * + * @param {String} path - relative path to file. + * + * @returns {Object|Null} File or NULL + */ + getFile = function (path) { + try { + return require(getFullPath(path)); + } catch (error) { + return null; + } }, /** * Immediately invoked function. * Loads user config file. */ - userConfig: (function () { + userConfig = (function () { try { return require(process.cwd() + '/grunt-config'); } catch (error) { return null; } - })(), + })(); + +module.exports = { /** * Loads file. @@ -29,32 +54,30 @@ module.exports = { * From default config with ".loc" suffix ; * From default config; * - * @returns themes file or error + * @param {String} alias + * + * @returns {Object} themes file or error */ - get: function (file) { - if (this.userConfig && this.userConfig[file]) { - return require(this.getFullPath(this.userConfig[file])); + get: function (alias) { + var tmp; + + if (userConfig && userConfig[alias]) { + return require(getFullPath(userConfig[alias])); + } else if (tmp = getFile(defaultConfig[alias] + '.loc') || getFile(defaultConfig[alias])) { + return tmp; } else { - try { - return require(this.getFullPath(this.defaultConfig[file] + '.loc')); - } catch (error) { - try { - return require(this.getFullPath(this.defaultConfig[file])); - } catch (error) { - throw error; - } - } + throw new Error('Cannot find file. Alias "' + alias + '" not set. ' + + 'Use "filesRouter.set" method to set it.').stack; } }, /** - * Generates full path to file. + * Sets file alias. * - * @param {String} path - relative path to file. - * - * @returns {String} Full path to file + * @param {String} alias + * @param {String} path */ - getFullPath: function (path) { - return process.cwd() + '/' + path; + set: function (alias, path) { + defaultConfig[alias] = path; } }; -- GitLab From 7959d63191f9e1729879211592d7667f803331cf Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Fri, 26 Aug 2016 11:40:39 +0300 Subject: [PATCH 681/838] MAGETWO-55345: Grunt uses actual theme's list --- Gruntfile.js.sample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js.sample b/Gruntfile.js.sample index ae7fca38bc6..dce7d377a78 100644 --- a/Gruntfile.js.sample +++ b/Gruntfile.js.sample @@ -16,8 +16,8 @@ module.exports = function (grunt) { tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'), themes; - filesRouter.set('themes', 'dev/tools/grunt/configs/themes') - themes = filesRouter.get('themes') + filesRouter.set('themes', 'dev/tools/grunt/configs/themes')ж + themes = filesRouter.get('themes')ж tasks = _.map(tasks, function(task){ return task.replace('.js', '') }); tasks.push('time-grunt'); -- GitLab From a441f2218c31115b8ff438800f492a7583b17fa9 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Fri, 26 Aug 2016 11:41:08 +0300 Subject: [PATCH 682/838] MAGETWO-55345: Grunt uses actual theme's list --- Gruntfile.js.sample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js.sample b/Gruntfile.js.sample index dce7d377a78..3bd874be048 100644 --- a/Gruntfile.js.sample +++ b/Gruntfile.js.sample @@ -16,8 +16,8 @@ module.exports = function (grunt) { tasks = grunt.file.expand('./dev/tools/grunt/tasks/*'), themes; - filesRouter.set('themes', 'dev/tools/grunt/configs/themes')ж - themes = filesRouter.get('themes')ж + filesRouter.set('themes', 'dev/tools/grunt/configs/themes'); + themes = filesRouter.get('themes'); tasks = _.map(tasks, function(task){ return task.replace('.js', '') }); tasks.push('time-grunt'); -- GitLab From a85facdcdc565c7a217e5049c0b90e66859962f5 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Fri, 26 Aug 2016 11:54:24 +0300 Subject: [PATCH 683/838] MAGETWO-54054: Compiler performance optimization - MAGETWO-50778: Minor code style fix - MAGETWO-57139: Minor code style fix --- lib/internal/Magento/Framework/Module/Dir/Reader.php | 2 +- setup/src/Magento/Setup/Console/Command/DiCompileCommand.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Module/Dir/Reader.php b/lib/internal/Magento/Framework/Module/Dir/Reader.php index 99bbe9ad834..353f7e51c59 100644 --- a/lib/internal/Magento/Framework/Module/Dir/Reader.php +++ b/lib/internal/Magento/Framework/Module/Dir/Reader.php @@ -95,7 +95,7 @@ class Reader /** * Retrieve iterator for files with $filename from components located in component $subDir. * - * @param $filename + * @param string $filename * @param string $subDir * * @return FileIterator diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index a1ad9bab5b2..3f577d9b311 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -203,7 +203,7 @@ class DiCompileCommand extends Command * @param string[] $modulePaths * @return string[] */ - private function getExcludedModulePaths($modulePaths) + private function getExcludedModulePaths(array $modulePaths) { $modulesByBasePath = []; foreach ($modulePaths as $modulePath) { @@ -237,7 +237,7 @@ class DiCompileCommand extends Command * @param string[] $libraryPaths * @return string[] */ - private function getExcludedLibraryPaths($libraryPaths) + private function getExcludedLibraryPaths(array $libraryPaths) { $excludedLibraryPaths = [ '#^(?:' . join('|', $libraryPaths) . ')/([\\w]+/)?Test#', -- GitLab From a6de866f3853562ff6b4b27f911b87e23f08b9f0 Mon Sep 17 00:00:00 2001 From: Volodymyr Zaets <vzaets@magento.com> Date: Fri, 26 Aug 2016 12:14:53 +0300 Subject: [PATCH 684/838] MAGETWO-52788: Dynamic Rows: support status being changed --- .../Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js index 041501b7410..51f5973372d 100644 --- a/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js +++ b/app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows.js @@ -441,7 +441,7 @@ define([ * Filters out deleted items from array * * @param {Array} data - * + * * @returns {Array} filtered array */ arrayFilter: function (data) { -- GitLab From 081fda9629822a27f5734b6a89347a0e7ecd16fd Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Fri, 26 Aug 2016 12:24:27 +0300 Subject: [PATCH 685/838] MAGETWO-56873: B2B does not supports in Web Setup Wizard --- setup/src/Magento/Setup/Model/SystemPackage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/src/Magento/Setup/Model/SystemPackage.php b/setup/src/Magento/Setup/Model/SystemPackage.php index 5aa048e27c0..56f149a5c50 100755 --- a/setup/src/Magento/Setup/Model/SystemPackage.php +++ b/setup/src/Magento/Setup/Model/SystemPackage.php @@ -37,6 +37,7 @@ class SystemPackage const EDITION_COMMUNITY = 'magento/product-community-edition'; const EDITION_ENTERPRISE = 'magento/product-enterprise-edition'; const EDITION_B2B = 'magento/product-b2b-edition'; + /**#@-*/ /** * Constructor -- GitLab From 426a43024119450b601edeecf7760ba152b88956 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Fri, 26 Aug 2016 12:53:19 +0300 Subject: [PATCH 686/838] MAGETWO-57135: Product import with images not working --- .../CatalogImportExport/Model/Import/Uploader.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index 4dfde3887df..fcc544f4cb8 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -155,7 +155,8 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader $filePath = $this->_directory->getRelativePath($this->getTmpDir() . '/' . $fileName); $this->_setUploadFile($filePath); - $result = $this->save($this->getDestDir()); + $destDir = $this->_directory->getAbsolutePath($this->getDestDir()); + $result = $this->save($destDir); $result['name'] = self::getCorrectFileName($result['name']); return $result; } @@ -305,11 +306,10 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader $tmpRealPath = $this->_directory->getDriver()->getRealPath( $this->_directory->getAbsolutePath($tmpPath) ); - $destinationRealPath = $this->_directory->getDriver()->getRealPath( - $this->_directory->getAbsolutePath($destPath) - ); + $destinationRealPath = $this->_directory->getDriver()->getRealPath($destPath); + $relativeDestPath = $this->_directory->getRelativePath($destPath); $isSameFile = $tmpRealPath === $destinationRealPath; - return $isSameFile ?: $this->_directory->copyFile($tmpPath, $destPath); + return $isSameFile ?: $this->_directory->copyFile($tmpPath, $relativeDestPath); } else { return false; } -- GitLab From a4a436f152e848f4fcafad9e0124c4422e815554 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Fri, 26 Aug 2016 13:23:28 +0300 Subject: [PATCH 687/838] MAGETWO-57397: Update gallery entry via API doesn't work - for mainline --- .../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 9670b7e035e..54ca1948053 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -96,6 +96,7 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal foreach ($existingMediaGalleryEntries as $key => $existingEntry) { if ($existingEntry->getId() == $entry->getId()) { $found = true; + $entry->setId(null); $existingMediaGalleryEntries[$key] = $entry; break; } -- GitLab From 5ebc3d49ea13bbca7dc5544936c58cce389d1023 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Fri, 26 Aug 2016 14:49:59 +0300 Subject: [PATCH 688/838] MAGETWO-57397: Update gallery entry via API doesn't work - for mainline --- .../Product/Gallery/GalleryManagementTest.php | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 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 17dceef6c11..ea2ddca59f4 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 @@ -45,7 +45,7 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase { $this->productRepositoryMock = $this->getMock(\Magento\Catalog\Api\ProductRepositoryInterface::class); $this->contentValidatorMock = $this->getMock(\Magento\Framework\Api\ImageContentValidatorInterface::class); - $this->productMock = $this->getMock( + $this->productMock = $this->getMock( \Magento\Catalog\Model\Product::class, [ 'setStoreId', @@ -115,7 +115,7 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase public function testCreate() { $productSku = 'mediaProduct'; - $entryContentMock = $this->getMock( + $entryContentMock = $this->getMock( \Magento\Framework\Api\Data\ImageContentInterface::class ); $this->mediaGalleryEntryMock->expects($this->any())->method('getContent')->willReturn($entryContentMock); @@ -153,8 +153,8 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryId = 42; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn(43); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') @@ -174,8 +174,8 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryId = 42; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn($entryId); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') @@ -193,13 +193,14 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryId = 42; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn($entryId); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') ->willReturn([$existingEntryMock]); $entryMock->expects($this->once())->method('getId')->willReturn($entryId); + $entryMock->expects($this->once())->method('setId')->with(null); $this->productMock->expects($this->once())->method('setMediaGalleryEntries') ->willReturn([$entryMock]); @@ -217,8 +218,8 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryId = 42; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn(43); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') @@ -232,8 +233,8 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $entryId = 42; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn(42); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') @@ -267,8 +268,8 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $imageId = 43; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn(44); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') @@ -282,8 +283,8 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $imageId = 42; $this->productRepositoryMock->expects($this->once())->method('get')->with($productSku) ->willReturn($this->productMock); - $existingEntryMock = $this->getMock( - \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class + $existingEntryMock = $this->getMock( + \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface::class ); $existingEntryMock->expects($this->once())->method('getId')->willReturn(42); $this->productMock->expects($this->once())->method('getMediaGalleryEntries') -- GitLab From 4dc1931f480abcf4016f7cf69af8b62ee9fb039e Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 26 Aug 2016 07:57:00 -0500 Subject: [PATCH 689/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../Customer/view/adminhtml/templates/tab/cart.phtml | 12 ++++++------ .../templates/account/authentication-popup.phtml | 2 +- .../view/frontend/templates/address/book.phtml | 4 ++-- .../Customer/view/frontend/templates/form/edit.phtml | 6 +++--- .../view/frontend/templates/form/register.phtml | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml index c11ea7aa3bc..0fda50241ab 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/tab/cart.phtml @@ -34,14 +34,14 @@ require([ if (!params) { params = {}; } - <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.reloadParams = params; - <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.reload(); - <?php echo $block->escapeJs($block->escapeHtml($block->getJsObjectName())) ?>.reloadParams = {}; + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = params; + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reload(); + <?php echo $block->escapeJs($block->getJsObjectName()) ?>.reloadParams = {}; }, configureItem: function (itemId) { - productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($block->escapeHtml($listType)) ?>', this.cbOnLoadIframe.bind(this)); - productConfigure.showItemConfiguration('<?php echo $block->escapeJs($block->escapeHtml($listType)) ?>', itemId); + productConfigure.setOnLoadIFrameCallback('<?php echo $block->escapeJs($listType) ?>', this.cbOnLoadIframe.bind(this)); + productConfigure.showItemConfiguration('<?php echo $block->escapeJs($listType) ?>', itemId); return false; }, @@ -81,7 +81,7 @@ $params = [ ]; ?> productConfigure.addListType( - '<?php echo $block->escapeJs($block->escapeHtml($listType)) ?>', + '<?php echo $block->escapeJs($listType) ?>', { urlFetch: '<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/configure', $params))) ?>', urlConfirm: '<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('customer/cart_product_composite_cart/update', $params))) ?>' diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index f34cc41344e..2b62b1f6fb7 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -19,7 +19,7 @@ "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> }, "*": { - "Magento_Ui/js/block-loader": "<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('images/loader-1.gif'))); ?>" + "Magento_Ui/js/block-loader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-1.gif')); ?>" } } </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index 37ab2584c84..fe45a6132b0 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -99,9 +99,9 @@ ".page-main": { "address": { "deleteAddress": "li.item a[role='delete-address']", - "deleteUrlPrefix": "<?php echo $block->escapeJs($block->escapeUrl($block->getDeleteUrl())) ?>id/", + "deleteUrlPrefix": "<?php echo $block->escapeUrl($block->getDeleteUrl()) ?>id/", "addAddress": "button[role='add-address']", - "addAddressLocation": "<?php echo $block->escapeJs($block->escapeUrl($block->getAddAddressUrl())) ?>" + "addAddressLocation": "<?php echo $block->escapeUrl($block->getAddAddressUrl()) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 716378f4fc1..6c1d349a754 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -122,9 +122,9 @@ { "[data-role=change-email], [data-role=change-password]": { "changeEmailPassword": { - "titleChangeEmail": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Email'))) ?>", - "titleChangePassword": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Password'))) ?>", - "titleChangeEmailAndPassword": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Email and Password'))) ?>" + "titleChangeEmail": "<?php echo $block->escapeHtml(__('Change Email')) ?>", + "titleChangePassword": "<?php echo $block->escapeHtml(__('Change Password')) ?>", + "titleChangeEmailAndPassword": "<?php echo $block->escapeHtml(__('Change Email and Password')) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index fb51e056d16..f9fe8c69b48 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -210,7 +210,7 @@ require([ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->escapeHtml($block->getFormData()->getRegionId())) ?>", + "defaultRegion": "<?php echo $block->escapeHtml($block->getFormData()->getRegionId()) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getCountriesWithOptionalZip(true) ?> } } -- GitLab From df177be8fecda61b86d7c32045f4e732ab52138c Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 26 Aug 2016 08:43:54 -0500 Subject: [PATCH 690/838] MAGETWO-57233: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../Magento/Cookie/view/frontend/templates/html/notices.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index e8e6d932950..d34214a3f7b 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -30,7 +30,7 @@ "cookieName": "<?php /* @noEscape */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", "cookieValue": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getAcceptedSaveCookiesWebsiteIds() ?>, "cookieLifetime": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getCookieRestrictionLifetime()?>, - "noCookiesUrl": "<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('cookie/index/noCookies'))) ?>" + "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" } } } -- GitLab From 582fc2dc8508d9ecad5480da4c80b525dc7f3b6f Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 26 Aug 2016 08:44:07 -0500 Subject: [PATCH 691/838] MAGETWO-57237: Eliminate @escapeNotVerified in Review Module --- app/code/Magento/Review/view/frontend/templates/review.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml index c3f64511b15..a7459ca7e1b 100644 --- a/app/code/Magento/Review/view/frontend/templates/review.phtml +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -13,7 +13,7 @@ { "*": { "Magento_Review/js/process-reviews": { - "productReviewUrl": "<?php echo $block->escapeJs($block->escapeUrl($block->getProductReviewUrl())); ?>" + "productReviewUrl": "<?php echo $block->escapeUrl($block->getProductReviewUrl()); ?>" } } } -- GitLab From 2653330d93eed56191a97f17095a8e006bbe3602 Mon Sep 17 00:00:00 2001 From: Dmytro Yushkin <dyushkin@magento.com> Date: Fri, 26 Aug 2016 16:53:00 +0300 Subject: [PATCH 692/838] MAGETWO-56801: [GITHUB] Fixed column description for "website_id" column #4388 - Upgraded module version --- app/code/Magento/CatalogInventory/etc/module.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/etc/module.xml b/app/code/Magento/CatalogInventory/etc/module.xml index 5c7ade1e83c..2224da524fc 100644 --- a/app/code/Magento/CatalogInventory/etc/module.xml +++ b/app/code/Magento/CatalogInventory/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_CatalogInventory" setup_version="2.0.0"> + <module name="Magento_CatalogInventory" setup_version="2.0.1"> <sequence> <module name="Magento_Catalog"/> </sequence> -- GitLab From 3ee655a31d78a9c9aaa82b0c1a396a61d73c4229 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Fri, 26 Aug 2016 17:22:55 +0300 Subject: [PATCH 693/838] MAGETWO-55908: Prepare PR --- .../Product/Form/Modifier/AdvancedPricing.php | 11 ++++----- .../Customer/Model/Config/Source/Group.php | 18 +++++++-------- .../Model/Config/Source/Group/Multiselect.php | 18 ++++++++++++--- .../Model/Customer/Attribute/Source/Group.php | 3 +-- .../GroupSourceLoggedInOnlyInterface.php} | 4 ++-- .../Customer/Model/Customer/Source/Group.php | 19 ++++----------- .../Customer/Source/GroupSourceInterface.php | 1 - .../GroupSourceWithAllGroupsInterface.php | 12 ---------- .../Source/GroupWithoutAllSources.php | 15 ------------ .../Config/Source/Group/MultiselectTest.php | 23 +++++++++++++------ .../Unit/Model/Config/Source/GroupTest.php | 6 ++--- app/code/Magento/Customer/etc/di.xml | 8 +++---- 12 files changed, 59 insertions(+), 79 deletions(-) rename app/code/Magento/Customer/Model/Customer/{Source/GroupSourceForLoggedInCustomersInterface.php => Attribute/Source/GroupSourceLoggedInOnlyInterface.php} (57%) delete mode 100644 app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php delete mode 100644 app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 1f85d81a5df..071bc8d7967 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -7,11 +7,10 @@ namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Model\Locator\LocatorInterface; -use Magento\Customer\Model\Customer\Source\GroupSourceWithAllGroupsInterface; +use Magento\Customer\Model\Customer\Source\GroupSourceInterface; use Magento\Directory\Helper\Data; use Magento\Framework\App\ObjectManager; use Magento\Store\Model\StoreManagerInterface; -use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -84,7 +83,7 @@ class AdvancedPricing extends AbstractModifier protected $meta = []; /** - * @var GroupSourceWithAllGroupsInterface + * @var GroupSourceInterface */ private $customerGroupSource; @@ -98,7 +97,7 @@ class AdvancedPricing extends AbstractModifier * @param Data $directoryHelper * @param ArrayManager $arrayManager * @param string $scopeName - * @param GroupSourceWithAllGroupsInterface $customerGroupSource + * @param GroupSourceInterface $customerGroupSource * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -111,7 +110,7 @@ class AdvancedPricing extends AbstractModifier Data $directoryHelper, ArrayManager $arrayManager, $scopeName = '', - GroupSourceWithAllGroupsInterface $customerGroupSource = null + GroupSourceInterface $customerGroupSource = null ) { $this->locator = $locator; $this->storeManager = $storeManager; @@ -123,7 +122,7 @@ class AdvancedPricing extends AbstractModifier $this->arrayManager = $arrayManager; $this->scopeName = $scopeName; $this->customerGroupSource = $customerGroupSource - ?: ObjectManager::getInstance()->get(GroupSourceWithAllGroupsInterface::class); + ?: ObjectManager::getInstance()->get(GroupSourceInterface::class); } /** diff --git a/app/code/Magento/Customer/Model/Config/Source/Group.php b/app/code/Magento/Customer/Model/Config/Source/Group.php index 76f0b142da0..e693bf7a3c4 100644 --- a/app/code/Magento/Customer/Model/Config/Source/Group.php +++ b/app/code/Magento/Customer/Model/Config/Source/Group.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Model\Config\Source; use Magento\Customer\Api\GroupManagementInterface; -use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; +use Magento\Customer\Model\Customer\Attribute\Source\GroupSourceLoggedInOnlyInterface; use Magento\Framework\App\ObjectManager; class Group implements \Magento\Framework\Option\ArrayInterface @@ -29,33 +29,33 @@ class Group implements \Magento\Framework\Option\ArrayInterface protected $_converter; /** - * @var GroupSourceForLoggedInCustomersInterface + * @var GroupSourceLoggedInOnlyInterface */ - private $groupSourceForLoggedInCustomers; + private $groupSourceLoggedInOnly; /** * @param GroupManagementInterface $groupManagement * @param \Magento\Framework\Convert\DataObject $converter - * @param GroupSourceForLoggedInCustomersInterface $groupSourceForLoggedInCustomers + * @param GroupSourceLoggedInOnlyInterface $groupSourceForLoggedInCustomers */ public function __construct( GroupManagementInterface $groupManagement, \Magento\Framework\Convert\DataObject $converter, - GroupSourceForLoggedInCustomersInterface $groupSourceForLoggedInCustomers = null + GroupSourceLoggedInOnlyInterface $groupSourceForLoggedInCustomers = null ) { $this->_groupManagement = $groupManagement; $this->_converter = $converter; - $this->groupSourceForLoggedInCustomers = $groupSourceForLoggedInCustomers - ?: ObjectManager::getInstance()->get(GroupSourceForLoggedInCustomersInterface::class); + $this->groupSourceLoggedInOnly = $groupSourceForLoggedInCustomers + ?: ObjectManager::getInstance()->get(GroupSourceLoggedInOnlyInterface::class); } /** - * @return array + * @inheritdoc */ public function toOptionArray() { if (!$this->_options) { - $this->_options = $this->groupSourceForLoggedInCustomers->toOptionArray(); + $this->_options = $this->groupSourceLoggedInOnly->toOptionArray(); array_unshift($this->_options, ['value' => '', 'label' => __('-- Please Select --')]); } diff --git a/app/code/Magento/Customer/Model/Config/Source/Group/Multiselect.php b/app/code/Magento/Customer/Model/Config/Source/Group/Multiselect.php index 708e3243e26..adfc78448cd 100644 --- a/app/code/Magento/Customer/Model/Config/Source/Group/Multiselect.php +++ b/app/code/Magento/Customer/Model/Config/Source/Group/Multiselect.php @@ -5,7 +5,9 @@ */ namespace Magento\Customer\Model\Config\Source\Group; +use Magento\Customer\Model\Customer\Attribute\Source\GroupSourceLoggedInOnlyInterface; use Magento\Customer\Api\GroupManagementInterface; +use Magento\Framework\App\ObjectManager; class Multiselect implements \Magento\Framework\Option\ArrayInterface { @@ -17,25 +19,36 @@ class Multiselect implements \Magento\Framework\Option\ArrayInterface protected $_options; /** + * @deprecated * @var GroupManagementInterface */ protected $_groupManagement; /** + * @deprecated * @var \Magento\Framework\Convert\DataObject */ protected $_converter; + /** + * @var GroupSourceLoggedInOnlyInterface + */ + private $groupSourceLoggedInOnly; + /** * @param GroupManagementInterface $groupManagement * @param \Magento\Framework\Convert\DataObject $converter + * @param GroupSourceLoggedInOnlyInterface|null $groupSourceLoggedInOnly */ public function __construct( GroupManagementInterface $groupManagement, - \Magento\Framework\Convert\DataObject $converter + \Magento\Framework\Convert\DataObject $converter, + GroupSourceLoggedInOnlyInterface $groupSourceLoggedInOnly = null ) { $this->_groupManagement = $groupManagement; $this->_converter = $converter; + $this->groupSourceLoggedInOnly = $groupSourceLoggedInOnly + ?: ObjectManager::getInstance()->get(GroupSourceLoggedInOnlyInterface::class); } /** @@ -46,8 +59,7 @@ class Multiselect implements \Magento\Framework\Option\ArrayInterface public function toOptionArray() { if (!$this->_options) { - $groups = $this->_groupManagement->getLoggedInGroups(); - $this->_options = $this->_converter->toOptionArray($groups, 'id', 'code'); + $this->_options = $this->groupSourceLoggedInOnly->toOptionArray(); } return $this->_options; } diff --git a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php index 22f196d0c2b..9af4b7fc673 100644 --- a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Group.php @@ -6,14 +6,13 @@ namespace Magento\Customer\Model\Customer\Attribute\Source; use Magento\Customer\Api\GroupManagementInterface; -use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; /** * Customer group attribute source * * @author Magento Core Team <core@magentocommerce.com> */ -class Group extends \Magento\Eav\Model\Entity\Attribute\Source\Table implements GroupSourceForLoggedInCustomersInterface +class Group extends \Magento\Eav\Model\Entity\Attribute\Source\Table implements GroupSourceLoggedInOnlyInterface { /** * @var GroupManagementInterface diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php b/app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php similarity index 57% rename from app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php rename to app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php index be44b12314b..93df78a1be1 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceForLoggedInCustomersInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php @@ -4,11 +4,11 @@ * See COPYING.txt for license details. */ -namespace Magento\Customer\Model\Customer\Source; +namespace Magento\Customer\Model\Customer\Attribute\Source; use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; -interface GroupSourceForLoggedInCustomersInterface extends OptionArrayInterface +interface GroupSourceLoggedInOnlyInterface extends OptionArrayInterface { } diff --git a/app/code/Magento/Customer/Model/Customer/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Source/Group.php index 068d960ea77..5973ec6ffaa 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Source/Group.php @@ -11,7 +11,7 @@ use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -class Group implements GroupSourceWithAllGroupsInterface +class Group implements GroupSourceInterface { /** * @var ModuleManager @@ -28,12 +28,6 @@ class Group implements GroupSourceWithAllGroupsInterface */ protected $searchCriteriaBuilder; - /** - * Defines is 'ALL GROUPS' value should be added to options - * @var bool - */ - protected $isShowAllGroupsValue = true; - /** * @param ModuleManager $moduleManager * @param GroupRepositoryInterface $groupRepository @@ -60,13 +54,10 @@ class Group implements GroupSourceWithAllGroupsInterface return []; } $customerGroups = []; - - if ($this->isShowAllGroupsValue) { - $customerGroups[] = [ - 'label' => __('ALL GROUPS'), - 'value' => GroupInterface::CUST_GROUP_ALL, - ]; - } + $customerGroups[] = [ + 'label' => __('ALL GROUPS'), + 'value' => GroupInterface::CUST_GROUP_ALL, + ]; /** @var GroupSearchResultsInterface $groups */ $groups = $this->groupRepository->getList($this->searchCriteriaBuilder->create()); diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php index 9d0cfe08af8..d180ad4d491 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php @@ -5,7 +5,6 @@ */ namespace Magento\Customer\Model\Customer\Source; - use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; interface GroupSourceInterface extends OptionArrayInterface diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php deleted file mode 100644 index 75150ef813e..00000000000 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceWithAllGroupsInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Customer\Model\Customer\Source; - -use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; - -interface GroupSourceWithAllGroupsInterface extends OptionArrayInterface -{ -} diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php b/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php deleted file mode 100644 index 44455b418c0..00000000000 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupWithoutAllSources.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Customer\Model\Customer\Source; - -class GroupWithoutAllSources extends Group implements GroupSourceInterface -{ - /** - * @var bool - */ - protected $isShowAllGroupsValue = false; -} diff --git a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/Group/MultiselectTest.php b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/Group/MultiselectTest.php index 3b8bea594ed..bc64351f3d0 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/Group/MultiselectTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/Group/MultiselectTest.php @@ -6,6 +6,8 @@ */ namespace Magento\Customer\Test\Unit\Model\Config\Source\Group; +use Magento\Customer\Model\Customer\Attribute\Source\GroupSourceLoggedInOnlyInterface; + class MultiselectTest extends \PHPUnit_Framework_TestCase { /** @@ -23,22 +25,29 @@ class MultiselectTest extends \PHPUnit_Framework_TestCase */ protected $converterMock; + /** + * @var GroupSourceLoggedInOnlyInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $groupSourceLoggedInOnly; + protected function setUp() { $this->groupServiceMock = $this->getMock(\Magento\Customer\Api\GroupManagementInterface::class); $this->converterMock = $this->getMock(\Magento\Framework\Convert\DataObject::class, [], [], '', false); - $this->model = - new \Magento\Customer\Model\Config\Source\Group\Multiselect($this->groupServiceMock, $this->converterMock); + $this->groupSourceLoggedInOnly = $this->getMockBuilder(GroupSourceLoggedInOnlyInterface::class)->getMock(); + $this->model = new \Magento\Customer\Model\Config\Source\Group\Multiselect( + $this->groupServiceMock, + $this->converterMock, + $this->groupSourceLoggedInOnly + ); } public function testToOptionArray() { $expectedValue = ['General', 'Retail']; - $this->groupServiceMock->expects($this->once()) - ->method('getLoggedInGroups') - ->will($this->returnValue($expectedValue)); - $this->converterMock->expects($this->once())->method('toOptionArray') - ->with($expectedValue, 'id', 'code')->will($this->returnValue($expectedValue)); + $this->groupServiceMock->expects($this->never())->method('getLoggedInGroups'); + $this->converterMock->expects($this->never())->method('toOptionArray'); + $this->groupSourceLoggedInOnly->expects($this->once())->method('toOptionArray')->willReturn($expectedValue); $this->assertEquals($expectedValue, $this->model->toOptionArray()); } } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php index d7693a25653..55b495f9c41 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Config/Source/GroupTest.php @@ -8,14 +8,14 @@ namespace Magento\Customer\Test\Unit\Model\Config\Source; use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Model\Config\Source\Group; -use Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface; +use Magento\Customer\Model\Customer\Attribute\Source\GroupSourceLoggedInOnlyInterface; use Magento\Framework\Convert\DataObject; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class GroupTest extends \PHPUnit_Framework_TestCase { /** - * @var GroupSourceForLoggedInCustomersInterface|\PHPUnit_Framework_MockObject_MockObject + * @var GroupSourceLoggedInOnlyInterface|\PHPUnit_Framework_MockObject_MockObject */ private $groupSource; @@ -38,7 +38,7 @@ class GroupTest extends \PHPUnit_Framework_TestCase { $this->groupServiceMock = $this->getMock(GroupManagementInterface::class); $this->converterMock = $this->getMock(DataObject::class, [], [], '', false); - $this->groupSource = $this->getMockBuilder(GroupSourceForLoggedInCustomersInterface::class) + $this->groupSource = $this->getMockBuilder(GroupSourceLoggedInOnlyInterface::class) ->getMockForAbstractClass(); $this->model = (new ObjectManager($this))->getObject( Group::class, diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index 5229a709ed4..ebde958f75b 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -51,12 +51,10 @@ type="Magento\Customer\Helper\View" /> <preference for="Magento\Customer\Model\Address\CustomAttributeListInterface" type="Magento\Customer\Model\Address\CustomAttributeList" /> - <preference for="Magento\Customer\Model\Customer\Source\GroupSourceWithAllGroupsInterface" - type="\Magento\Customer\Model\Customer\Source\Group" /> <preference for="Magento\Customer\Model\Customer\Source\GroupSourceInterface" - type="\Magento\Customer\Model\Customer\Source\GroupWithoutAllSources" /> - <preference for="Magento\Customer\Model\Customer\Source\GroupSourceForLoggedInCustomersInterface" - type="\Magento\Customer\Model\Customer\Attribute\Source\Group"/> + type="Magento\Customer\Model\Customer\Source\Group" /> + <preference for="Magento\Customer\Model\Customer\Attribute\Source\GroupSourceLoggedInOnlyInterface" + type="Magento\Customer\Model\Customer\Attribute\Source\Group"/> <type name="Magento\Customer\Model\Session"> <arguments> <argument name="configShare" xsi:type="object">Magento\Customer\Model\Config\Share\Proxy</argument> -- GitLab From 53de3d04217b88dacb5fab691f79260bea3571b6 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 26 Aug 2016 09:23:14 -0500 Subject: [PATCH 694/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 2 +- .../Framework/Test/Unit/EscaperTest.php | 47 ++++++++++++------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 9ee3b0aa9d4..ab9186821e2 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -74,7 +74,7 @@ class Escaper $nodes = $xpath->query('//node()[name() != \'' . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) . '\']'); foreach ($nodes as $node) { - if ($node->nodeName != '#text') { + if ($node->nodeName != '#text' && $node->nodeName != '#comment') { $node->parentNode->replaceChild($dom->createTextNode($node->textContent), $node); } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index a0b8b238a1e..493dd4742f0 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -46,20 +46,31 @@ class EscaperTest extends \PHPUnit_Framework_TestCase */ public function escapeHtmlDataProvider() { - $zendEscaper = new \Magento\Framework\ZendEscaper(); return [ 'array data' => [ - 'data' => ['one', '<two>three</two>'], - 'expected' => ['one', '<two>three</two>'], - null, + 'data' => [ + 'one', + '<two>three</two>' + ], + 'expected' => [ + 'one', + '<two>three</two>' + ], + [], ], 'string data conversion' => [ 'data' => '<two>three</two>', 'expected' => '<two>three</two>', - null, + [], + ], + 'string data no conversion' => [ + 'data' => 'one', + 'expected' => 'one' + ], + 'string data with special chars' => [ + 'data' => '&<>"\'', + 'expected' => '&<>"'' ], - 'string data no conversion' => ['data' => 'one', 'expected' => 'one'], - 'string data with special chars' => ['data' => '&<>"\'', 'expected' => '&<>"''], 'string data with allowed tags' => [ 'data' => '<span><b>some text in tags</b></span>', 'expected' => '<span><b>some text in tags</b></span>', @@ -90,11 +101,13 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'expected' => 'Only <span><b>2</b></span> in stock', 'allowedTags' => ['span', 'b'], ], -// 'string data with allowed tags with attributes 6' => [ -// 'data' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', -// 'expected' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', -// 'allowedTags' => ['span', 'b'], -// ], + /* + 'string data with allowed tags with attributes 6' => [ + 'data' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', + 'expected' => 'Only <span onclick=alert("<span>")><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + */ 'string data with allowed tags with attributes and not allowed tags' => [ 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> or <a href="%2">create an account</a>', @@ -105,11 +118,11 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'expected' => 'Some test <span>text in span tag</span> text in strong tag <a class="some-class" href="http://domain.com/">Click here</a>alert(1)', 'allowedTags' => ['a', 'span'], ], -// 'string data with allowed tags and html comment' => [ -// 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', -// 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', -// 'allowedTags' => ['span', 'b'], -// ], + 'string data with allowed tags and html comment' => [ + 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'allowedTags' => ['span', 'b'], + ], ]; } -- GitLab From f27635e8244fc20061a399a73915c082ec28489f Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 26 Aug 2016 09:33:46 -0500 Subject: [PATCH 695/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index ab9186821e2..60bc084ef55 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -36,7 +36,7 @@ class Escaper } } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { - $result = $this->escapeHtmlTagsAndAttributes($data, $allowedTags); + $result = $this->filterHtmlTagsAndAttributes($data, $allowedTags); } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } @@ -47,18 +47,21 @@ class Escaper } /** - * Escape not allowed HTML entities + * Filter not allowed HTML entities * * @param string $string * @param string[] $allowedTags * @return string */ - private function escapeHtmlTagsAndAttributes($string, $allowedTags) + private function filterHtmlTagsAndAttributes($string, $allowedTags) { $wrapperElementId = uniqid(); $dom = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( - function($errorNumber, $errorString, $errorFile, $errorLine) { + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + function ($errorNumber, $errorString, $errorFile, $errorLine) { throw new \Exception($errorString, $errorNumber); } ); -- GitLab From 8bf6a8596182137b3d37011364b5558ced754925 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 26 Aug 2016 09:40:20 -0500 Subject: [PATCH 696/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 60bc084ef55..19ffe83fa36 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -47,7 +47,7 @@ class Escaper } /** - * Filter not allowed HTML entities + * Filter not allowed tags and attribtues * * @param string $string * @param string[] $allowedTags -- GitLab From c05445091520c011ba538dc0a61fd84b5a342e5f Mon Sep 17 00:00:00 2001 From: Eugene Tulika <vranen@gmail.com> Date: Fri, 26 Aug 2016 19:10:35 +0300 Subject: [PATCH 697/838] MAGETWO-54460: Admin user with access to only one website is unable to edit a product - added test --- .../Collection/AbstractCollectionTest.php | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php b/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php index 1ea2a5205a5..b67eee9fd9e 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/ResourceModel/Rule/Collection/AbstractCollectionTest.php @@ -45,6 +45,16 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase */ protected $_db; + /** + * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $connectionMock; + + /** + * @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject + */ + private $selectMock; + protected function setUp() { $this->_entityFactoryMock = $this->getMock(\Magento\Framework\Data\Collection\EntityFactoryInterface::class); @@ -152,6 +162,30 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase ); } + public function testAddWebsiteFilterArray() + { + $this->selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->connectionMock->expects($this->atLeastOnce()) + ->method('quoteInto') + ->with($this->equalTo('website. IN (?)'), $this->equalTo(['2', '3'])) + ->willReturn(true); + + $this->abstractCollection->expects($this->atLeastOnce())->method('getSelect')->willReturn($this->selectMock); + $this->abstractCollection->expects($this->atLeastOnce())->method('getConnection') + ->willReturn($this->connectionMock); + + $this->assertInstanceOf( + \Magento\Rule\Model\ResourceModel\Rule\Collection\AbstractCollection::class, + $this->abstractCollection->addWebsiteFilter(['2', '3']) + ); + } + public function testAddFieldToFilter() { $this->_prepareAddFilterStubs(); -- GitLab From a88ff22e6c240a86675ed6e2b9675468aa024f2f Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Fri, 26 Aug 2016 19:30:51 +0300 Subject: [PATCH 698/838] MAGETWO-56534: CLONE - Price in cart does not update correctly when price is changed in admin. --- .../Model/Product/Plugin/UpdateQuoteItems.php | 44 +++++++++++++ .../Product/Plugin/UpdateQuoteItemsTest.php | 61 +++++++++++++++++++ app/code/Magento/Quote/etc/di.xml | 3 + 3 files changed, 108 insertions(+) create mode 100644 app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php create mode 100644 app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php diff --git a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php new file mode 100644 index 00000000000..94fe077741f --- /dev/null +++ b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php @@ -0,0 +1,44 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Quote\Model\Product\Plugin; + +class UpdateQuoteItems +{ + /** + * @var \Magento\Quote\Model\ResourceModel\Quote + */ + private $resource; + + /** + * @param \Magento\Quote\Model\ResourceModel\Quote $resource + */ + public function __construct( + \Magento\Quote\Model\ResourceModel\Quote $resource + ) + { + $this->resource = $resource; + } + + /** + * @param \Magento\Catalog\Model\ResourceModel\Product $subject + * @param \Closure $proceed + * @param \Magento\Catalog\Api\Data\ProductInterface $product + * @return mixed + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function aroundSave( + \Magento\Catalog\Model\ResourceModel\Product $subject, + \Closure $proceed, + \Magento\Catalog\Api\Data\ProductInterface $product + ) { + $result = $proceed($product); + $originalPrice = $product->getOrigData('price'); + if (!empty($originalPrice) && ($originalPrice != $product->getPrice())) { + $this->resource->markQuotesRecollect($product->getId()); + } + return $result; + } +} diff --git a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php new file mode 100644 index 00000000000..12d79a6da5e --- /dev/null +++ b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Quote\Test\Unit\Model\Product\Plugin; + +class UpdateQuoteItemsTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Quote\Model\Product\Plugin\UpdateQuoteItems + */ + private $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Quote\Model\ResourceModel\Quote + */ + private $quoteResource ; + + protected function setUp() + { + $this->quoteResource = $this->getMockBuilder(\Magento\Quote\Model\ResourceModel\Quote::class) + ->disableOriginalConstructor() + ->getMock(); + $this->model = new \Magento\Quote\Model\Product\Plugin\UpdateQuoteItems($this->quoteResource); + } + + /** + * @dataProvider aroundUpdateDataProvider + * @param int $originalPrice + * @param int $newPrice + * @param bool $callMethod + */ + public function testAroundUpdate($originalPrice, $newPrice, $callMethod) + { + $productResourceMock = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false); + $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getOrigData']) + ->getMockForAbstractClass(); + $closure = function () use ($productResourceMock) { + return $productResourceMock; + }; + $productId = 1; + $productMock->expects($this->any())->method('getOrigData')->with('price')->willReturn($originalPrice); + $productMock->expects($this->any())->method('getPrice')->willReturn($newPrice); + $productMock->expects($this->any())->method('getId')->willReturn($productId); + $this->quoteResource->expects($this->$callMethod())->method('markQuotesRecollect')->with($productId); + $result = $this->model->aroundSave($productResourceMock, $closure, $productMock); + $this->assertEquals($result, $productResourceMock); + } + + public function aroundUpdateDataProvider() + { + return [ + [10, 20, 'once'], + [null, 10, 'never'], + [10, 10, 'never'] + ]; + } +} diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml index 384f5ca143b..c4b1f9d1ce8 100644 --- a/app/code/Magento/Quote/etc/di.xml +++ b/app/code/Magento/Quote/etc/di.xml @@ -93,4 +93,7 @@ <type name="Magento\Catalog\Model\ResourceModel\Product"> <plugin name="clean_quote_items_after_product_delete" type="Magento\Quote\Model\Product\Plugin\RemoveQuoteItems"/> </type> + <type name="Magento\Catalog\Model\ResourceModel\Product"> + <plugin name="update_quote_items_after_product_save" type="Magento\Quote\Model\Product\Plugin\UpdateQuoteItems"/> + </type> </config> -- GitLab From 343dc7d259e2d9de96efc91b7a1a3c803727cb75 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Fri, 26 Aug 2016 15:13:40 -0500 Subject: [PATCH 699/838] MAGETWO-55589: Wrong algorithm for calculation batch size on category indexing - covered changes with unit tests --- .../Framework/DB/Query/BatchIterator.php | 31 ++- .../Test/DB/Query/BatchIteratorTest.php | 182 ++++++++++++++++++ .../Framework/Test/DB/Query/GeneratorTest.php | 141 ++++++++++++++ 3 files changed, 349 insertions(+), 5 deletions(-) create mode 100644 lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php create mode 100644 lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php diff --git a/lib/internal/Magento/Framework/DB/Query/BatchIterator.php b/lib/internal/Magento/Framework/DB/Query/BatchIterator.php index 86a1a73a20c..cf5e88c1b99 100644 --- a/lib/internal/Magento/Framework/DB/Query/BatchIterator.php +++ b/lib/internal/Magento/Framework/DB/Query/BatchIterator.php @@ -58,6 +58,11 @@ class BatchIterator implements \Iterator */ private $rangeFieldAlias; + /** + * @var bool + */ + private $isValid = true; + /** * Initialize dependencies. * @@ -87,6 +92,11 @@ class BatchIterator implements \Iterator */ public function current() { + if (null == $this->currentSelect) { + $this->currentSelect = $this->initSelectObject(); + $itemsCount = $this->calculateBatchSize($this->currentSelect); + $this->isValid = $itemsCount > 0; + } return $this->currentSelect; } @@ -95,7 +105,18 @@ class BatchIterator implements \Iterator */ public function next() { - $this->iteration++; + if (null == $this->currentSelect) { + $this->current(); + } + $select = $this->initSelectObject(); + $itemsCountInSelect = $this->calculateBatchSize($select); + $this->isValid = $itemsCountInSelect > 0; + if ($this->isValid) { + $this->iteration++; + $this->currentSelect = $select; + } else { + $this->currentSelect = null; + } return $this->currentSelect; } @@ -112,9 +133,7 @@ class BatchIterator implements \Iterator */ public function valid() { - $this->currentSelect = $this->initSelectObject(); - $batchSize = $this->calculateBatchSize($this->currentSelect); - return $batchSize > 0; + return $this->isValid; } /** @@ -123,7 +142,9 @@ class BatchIterator implements \Iterator public function rewind() { $this->minValue = 0; + $this->currentSelect = null; $this->iteration = 0; + $this->isValid = true; } /** @@ -165,7 +186,7 @@ class BatchIterator implements \Iterator /** * Reset sort order section from origin select object */ - $object->order($this->correlationName . '.' . $this->rangeField . ' asc'); + $object->order($this->correlationName . '.' . $this->rangeField . ' ' . \Magento\Framework\DB\Select::SQL_ASC); return $object; } } diff --git a/lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php b/lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php new file mode 100644 index 00000000000..f7adfce36a9 --- /dev/null +++ b/lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php @@ -0,0 +1,182 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Test\Unit\DB\Query; + +use Magento\Framework\DB\Query\BatchIterator; +use Magento\Framework\DB\Select; +use Magento\Framework\DB\Adapter\AdapterInterface; + +class BatchIteratorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var BatchIterator + */ + private $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $selectMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $wrapperSelectMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $connectionMock; + + private $batchSize; + private $correlationName; + private $rangeField; + private $rangeFieldAlias; + + protected function setUp() + { + $this->batchSize = 10; + $this->correlationName = 'correlationName'; + $this->rangeField = 'rangeField'; + $this->rangeFieldAlias = 'rangeFieldAlias'; + + $this->selectMock = $this->getMock(Select::class, [], [], '', false, false); + $this->wrapperSelectMock = $this->getMock(Select::class, [], [], '', false, false); + $this->connectionMock = $this->getMock(AdapterInterface::class); + $this->connectionMock->expects($this->any())->method('select')->willReturn($this->wrapperSelectMock); + $this->selectMock->expects($this->once())->method('getConnection')->willReturn($this->connectionMock); + $this->connectionMock->expects($this->any())->method('quoteIdentifier')->willReturnArgument(0); + + $this->model = new BatchIterator( + $this->selectMock, + $this->batchSize, + $this->correlationName, + $this->rangeField, + $this->rangeFieldAlias + ); + } + + /** + * Test steps: + * 1. $iterator->current(); + * 2. $iterator->current(); + * 3. $iterator->key(); + */ + public function testCurrent() + { + $filed = $this->correlationName . '.' . $this->rangeField; + + $this->selectMock->expects($this->once())->method('where')->with($filed . ' > ?', 0); + $this->selectMock->expects($this->once())->method('limit')->with($this->batchSize); + $this->selectMock->expects($this->once())->method('order')->with($filed . ' ASC'); + $this->assertEquals($this->selectMock, $this->model->current()); + $this->assertEquals($this->selectMock, $this->model->current()); + $this->assertEquals(0, $this->model->key()); + } + + /** + * SQL: select * from users + * Batch size: 10 + * IDS: [1 - 25] + * Items count: 25 + * Expected batches: [1-10, 11-20, 20-25] + * + * Test steps: + * 1. $iterator->rewind(); + * 2. $iterator->valid(); + * 3. $iterator->current(); + * 4. $iterator->key(); + * + * 1. $iterator->next() + * 2. $iterator->valid(); + * 3. $iterator->current(); + * 4. $iterator->key(); + * + * 1. $iterator->next() + * 2. $iterator->valid(); + * 3. $iterator->current(); + * 4. $iterator->key(); + * + * + * 1. $iterator->next() + * 2. $iterator->valid(); + * + */ + public function testIterations() + { + $startCallIndex = 3; + $stepCall = 4; + + $this->connectionMock->expects($this->at($startCallIndex)) + ->method('fetchRow') + ->willReturn(['max' => 10, 'cnt' => 10]); + + $this->connectionMock->expects($this->at($startCallIndex += $stepCall)) + ->method('fetchRow') + ->willReturn(['max' => 20, 'cnt' => 10]); + + $this->connectionMock->expects($this->at($startCallIndex += $stepCall)) + ->method('fetchRow') + ->willReturn(['max' => 25, 'cnt' => 5]); + + $this->connectionMock->expects($this->at($startCallIndex += $stepCall)) + ->method('fetchRow') + ->willReturn(['max' => null, 'cnt' => 0]); + + /** + * Test 3 iterations + * [1-10, 11-20, 20-25] + */ + $iteration = 0; + $result = []; + foreach ($this->model as $key => $select) { + $result[] = $select; + $this->assertEquals($iteration, $key); + $iteration++; + } + $this->assertCount(3, $result); + } + + /** + * Test steps: + * 1. $iterator->next(); + * 2. $iterator->key() + * 3. $iterator->next(); + * 4. $iterator->current() + * 5. $iterator->key() + */ + public function testNext() + { + $filed = $this->correlationName . '.' . $this->rangeField; + $this->selectMock->expects($this->at(0))->method('where')->with($filed . ' > ?', 0); + $this->selectMock->expects($this->exactly(3))->method('limit')->with($this->batchSize); + $this->selectMock->expects($this->exactly(3))->method('order')->with($filed . ' ASC'); + $this->selectMock->expects($this->at(3))->method('where')->with($filed . ' > ?', 25); + + $this->wrapperSelectMock->expects($this->exactly(3))->method('from')->with( + $this->selectMock, + [ + new \Zend_Db_Expr('MAX(' . $this->rangeFieldAlias . ') as max'), + new \Zend_Db_Expr('COUNT(*) as cnt') + ] + ); + $this->connectionMock->expects($this->exactly(3)) + ->method('fetchRow') + ->with($this->wrapperSelectMock) + ->willReturn([ + 'max' => 25, + 'cnt' => 10 + ] + ); + + $this->assertEquals($this->selectMock, $this->model->next()); + $this->assertEquals(1, $this->model->key()); + + $this->assertEquals($this->selectMock, $this->model->next()); + $this->assertEquals($this->selectMock, $this->model->current()); + $this->assertEquals(2, $this->model->key()); + } +} diff --git a/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php b/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php new file mode 100644 index 00000000000..dc54ef30331 --- /dev/null +++ b/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php @@ -0,0 +1,141 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Test\Unit\DB\Query; + +use Magento\Framework\DB\Query\Generator; +use Magento\Framework\DB\Query\BatchIteratorFactory; +use Magento\Framework\DB\Select; +use Magento\Framework\DB\Query\BatchIterator; + +class GeneratorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Generator + */ + private $model; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $selectMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $factoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $iteratorMock; + + protected function setUp() + { + $this->factoryMock = $this->getMock(BatchIteratorFactory::class, [], [], '', false, false); + $this->selectMock = $this->getMock(Select::class, [], [], '', false, false); + $this->iteratorMock = $this->getMock(BatchIterator::class, [], [], '', false, false); + $this->model = new Generator($this->factoryMock); + } + + public function testGenerate() + { + $map = [ + [ + Select::FROM, + [ + 'cp' => ['joinType' => Select::FROM] + ] + ], + [ + Select::COLUMNS, + [ + ['cp', 'entity_id', 'product_id'] + ] + ] + ]; + $this->selectMock->expects($this->exactly(2))->method('getPart')->willReturnMap($map); + $this->factoryMock->expects($this->once())->method('create')->with( + [ + 'select' => $this->selectMock, + 'batchSize' => 100, + 'correlationName' => 'cp', + 'rangeField' => 'entity_id', + 'rangeFieldAlias' => 'product_id' + ] + )->willReturn($this->iteratorMock); + $this->assertEquals($this->iteratorMock, $this->model->generate('entity_id', $this->selectMock, 100)); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Select object must have correct "FROM" part + */ + public function testGenerateWithoutFromPart() + { + $map = [ + [Select::FROM, []], + [ + Select::COLUMNS, + [ + ['cp', 'entity_id', 'product_id'] + ] + ] + ]; + $this->selectMock->expects($this->any())->method('getPart')->willReturnMap($map); + $this->factoryMock->expects($this->never())->method('create'); + $this->model->generate('entity_id', $this->selectMock, 100); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Select object must have correct range field name "entity_id" + */ + public function testGenerateWithInvalidRangeField() + { + $map = [ + [ + Select::FROM, + [ + 'cp' => ['joinType' => Select::FROM] + ] + ], + [ + Select::COLUMNS, + [ + ['cp', 'row_id', 'product_id'] + ] + ] + ]; + $this->selectMock->expects($this->exactly(2))->method('getPart')->willReturnMap($map); + $this->factoryMock->expects($this->never())->method('create'); + $this->model->generate('entity_id', $this->selectMock, 100); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Select object must have correct range field name "entity_id" + */ + public function testGenerateWithInvalidRangeFieldValue() + { + $map = [ + [ + Select::FROM, + [ + 'cp' => ['joinType' => Select::FROM] + ] + ], + [ + Select::COLUMNS, + [ + ['cp', new \Zend_Db_Expr('MAX(entity_id) as max'), 'product_id'] + ] + ] + ]; + $this->selectMock->expects($this->exactly(2))->method('getPart')->willReturnMap($map); + $this->factoryMock->expects($this->never())->method('create'); + $this->model->generate('entity_id', $this->selectMock, 100); + } +} -- GitLab From 0266e6b02bf750ed9b53e4cda087fac5c6901a0c Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Fri, 26 Aug 2016 15:18:33 -0500 Subject: [PATCH 700/838] MAGETWO-55871: Eliminate @escapeNotVerified in Email module - Eliminated all instances. - Fixed indentation. --- .../adminhtml/templates/template/edit.phtml | 40 +++++++++---------- .../templates/template/preview.phtml | 2 +- .../templates/session/activity.phtml | 3 +- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml index 26a70c64188..66be7b59ad1 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml @@ -11,20 +11,20 @@ use Magento\Framework\App\TemplateTypesInterface; /** @var $block \Magento\Email\Block\Adminhtml\Template\Edit */ ?> <?php if (!$block->getEditMode()): ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getLoadUrl() ?>" method="post" id="email_template_load_form"> +<form action="<?php echo $block->escapeUrl($block->getLoadUrl()) ?>" method="post" id="email_template_load_form"> <?php echo $block->getBlockHtml('formkey')?> <fieldset class="admin__fieldset form-inline"> - <legend class="admin__legend"><span><?php /* @escapeNotVerified */ echo __('Load default template') ?></span></legend><br> + <legend class="admin__legend"><span><?php echo $block->escapeHtml(__('Load default template')) ?></span></legend><br> <div class="admin__field"> - <label class="admin__field-label" for="template_select"><?php /* @escapeNotVerified */ echo __('Template') ?></label> + <label class="admin__field-label" for="template_select"><?php echo $block->escapeHtml(__('Template')) ?></label> <div class="admin__field-control"> <select id="template_select" name="code" class="admin__control-select required-entry"> <?php foreach ($block->getTemplateOptions() as $group => $options): ?> <?php if ($group): ?> - <optgroup label="<?php echo $block->escapeHtml($group) ?>"> + <optgroup label="<?php echo $block->escapeHtmlAttr($group) ?>"> <?php endif; ?> <?php foreach ($options as $option): ?> - <option value="<?php echo $block->escapeHtml($option['value']) ?>"<?php /* @escapeNotVerified */ echo $block->getOrigTemplateCode() == $option['value'] ? ' selected="selected"' : '' ?>><?php echo $block->escapeHtml($option['label']) ?></option> + <option value="<?php echo $block->escapeHtmlAttr($option['value']) ?>"<?php echo /* @noEscape */ $block->getOrigTemplateCode() == $option['value'] ? ' selected="selected"' : '' ?>><?php echo $block->escapeHtml($option['label']) ?></option> <?php endforeach; ?> <?php if ($group): ?> </optgroup> @@ -36,24 +36,24 @@ use Magento\Framework\App\TemplateTypesInterface; <div class="admin__field required"> <span class="admin__field-label"></span> <div class="admin__field-control"> - <?php echo $block->getLoadButtonHtml() ?> + <?php /* @noEscape */ echo $block->getLoadButtonHtml() ?> </div> </div> </fieldset> </form> <?php endif ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" id="email_template_edit_form"> - <?php echo $block->getBlockHtml('formkey')?> +<form action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" method="post" id="email_template_edit_form"> + <?php /* @noEscape */ echo $block->getBlockHtml('formkey')?> <input type="hidden" id="change_flag_element" name="_change_type_flag" value="" /> - <input type="hidden" id="orig_template_code" name="orig_template_code" value="<?php /* @escapeNotVerified */ echo $block->getOrigTemplateCode() ?>" /> - <?php echo $block->getFormHtml() ?> + <input type="hidden" id="orig_template_code" name="orig_template_code" value="<?php echo $block->escapeHtmlAttr($block->getOrigTemplateCode()) ?>" /> + <?php /* @noEscape */ echo $block->getFormHtml() ?> </form> -<form action="<?php /* @escapeNotVerified */ echo $block->getPreviewUrl() ?>" method="post" id="email_template_preview_form" target="_blank"> - <?php echo $block->getBlockHtml('formkey')?> +<form action="<?php echo $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="email_template_preview_form" target="_blank"> + <?php /* @noEscape */ echo $block->getBlockHtml('formkey')?> <div class="no-display"> - <input type="hidden" id="preview_type" name="type" value="<?php /* @escapeNotVerified */ echo $block->isTextType() ? 1 : 2 ?>" /> + <input type="hidden" id="preview_type" name="type" value="<?php /* @noEscape */ echo $block->isTextType() ? 1 : 2 ?>" /> <input type="hidden" id="preview_text" name="text" value="" /> <input type="hidden" id="preview_styles" name="styles" value="" /> </div> @@ -93,7 +93,7 @@ require([ this.bindEvents(); - this.renderPaths(<?php /* @escapeNotVerified */ echo $block->getCurrentlyUsedForPaths(); ?>, 'currently_used_for'); + this.renderPaths(<?php /* @noEscape */ echo $block->getCurrentlyUsedForPaths(); ?>, 'currently_used_for'); }, bindEvents: function(){ @@ -115,7 +115,7 @@ require([ }, stripTags: function () { - if(!window.confirm("<?php /* @escapeNotVerified */ echo __('Are you sure you want to strip tags?') ?>")) { + if(!window.confirm("<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure you want to strip tags?'))) ?>")) { return false; } this.unconvertedText = $('template_text').value; @@ -146,9 +146,9 @@ require([ }, preview: function() { if (this.typeChange) { - $('preview_type').value = <?php /* @escapeNotVerified */ echo TemplateTypesInterface::TYPE_TEXT ?>; + $('preview_type').value = <?php /* @noEscape */ echo TemplateTypesInterface::TYPE_TEXT ?>; } else { - $('preview_type').value = <?php /* @escapeNotVerified */ echo $block->getTemplateType() ?>; + $('preview_type').value = <?php echo (int) $block->getTemplateType() ?>; } if (typeof tinyMCE == 'undefined' || !tinyMCE.getInstanceById('template_text')) { $('preview_text').value = $('template_text').value; @@ -166,8 +166,8 @@ require([ }, deleteTemplate: function() { - if(window.confirm("<?php /* @escapeNotVerified */ echo __('Are you sure you want to delete this template?') ?>")) { - window.location.href = '<?php /* @escapeNotVerified */ echo $block->getDeleteUrl() ?>'; + if(window.confirm("<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure you want to delete this template?'))) ?>")) { + window.location.href = '<?php echo $block->escapeJs($block->escapeUrl($block->getDeleteUrl())) ?>'; } }, @@ -212,7 +212,7 @@ require([ }.bind(this)); } else { alert({ - content: '<?php /* @escapeNotVerified */ echo __('The template did not load. Please review the log for details.') ?>' + content: '<?php echo $block->escapeJs($block->escapeHtml(__('The template did not load. Please review the log for details.'))) ?>' }); } }.bind(this) diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml index 53340c2e2a7..f030b675577 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml @@ -10,7 +10,7 @@ <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title><?php /* @escapeNotVerified */ echo __('Email Preview'); ?></title> + <title><?php echo $block->escapeHtml(__('Email Preview')); ?></title> </head> <body> <?php echo $block->getChildHtml('content') ?> diff --git a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml index 9ae4c9f62af..d29147ae7f4 100644 --- a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml +++ b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml @@ -56,7 +56,8 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); data-mage-init='{"confirmRedirect":{ "message": "<?php echo $block->escapeJs(__('Are you sure that you want to log out all other sessions?')) ?>", - "url":"<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/logoutAll'))) ?>" + "url":"<?php + echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/logoutAll'))) ?>" }}' <?php else: ?>disabled<?php -- GitLab From 92e4efa66c077f37432d2793ec931a1a17e64f12 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Fri, 26 Aug 2016 15:46:06 -0500 Subject: [PATCH 701/838] MAGETWO-55589: Wrong algorithm for calculation batch size on category indexing --- .../Magento/Framework/DB/Query/Generator.php | 15 ++------ .../Framework/Test/DB/Query/GeneratorTest.php | 36 +++++++++++-------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/lib/internal/Magento/Framework/DB/Query/Generator.php b/lib/internal/Magento/Framework/DB/Query/Generator.php index 1873418968b..43f8388d3f4 100644 --- a/lib/internal/Magento/Framework/DB/Query/Generator.php +++ b/lib/internal/Magento/Framework/DB/Query/Generator.php @@ -57,24 +57,15 @@ class Generator /** * Calculate $rangeField alias */ - $rangeFieldAlias = null; + $rangeFieldAlias = $rangeField; foreach ($columns as $column) { list($table, $columnName, $alias) = $column; - if (is_string($columnName) && $table == $fieldCorrelationName && $columnName == $rangeField) { - $rangeFieldAlias = $alias; + if ($table == $fieldCorrelationName && $columnName == $rangeField) { + $rangeFieldAlias = $alias ?: $rangeField; break; } } - if (!$rangeFieldAlias) { - throw new LocalizedException( - new \Magento\Framework\Phrase( - 'Select object must have correct range field name "%field"', - ['field' => $rangeField] - ) - ); - } - return $this->iteratorFactory->create( [ 'select' => $select, diff --git a/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php b/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php index dc54ef30331..0278871d808 100644 --- a/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php +++ b/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php @@ -89,10 +89,6 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase $this->model->generate('entity_id', $this->selectMock, 100); } - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage Select object must have correct range field name "entity_id" - */ public function testGenerateWithInvalidRangeField() { $map = [ @@ -105,19 +101,23 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase [ Select::COLUMNS, [ - ['cp', 'row_id', 'product_id'] + ['cp', 'entity_id', null] ] ] ]; $this->selectMock->expects($this->exactly(2))->method('getPart')->willReturnMap($map); - $this->factoryMock->expects($this->never())->method('create'); - $this->model->generate('entity_id', $this->selectMock, 100); + $this->factoryMock->expects($this->once())->method('create')->with( + [ + 'select' => $this->selectMock, + 'batchSize' => 100, + 'correlationName' => 'cp', + 'rangeField' => 'entity_id', + 'rangeFieldAlias' => 'entity_id' + ] + )->willReturn($this->iteratorMock); + $this->assertEquals($this->iteratorMock, $this->model->generate('entity_id', $this->selectMock, 100)); } - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage Select object must have correct range field name "entity_id" - */ public function testGenerateWithInvalidRangeFieldValue() { $map = [ @@ -130,12 +130,20 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase [ Select::COLUMNS, [ - ['cp', new \Zend_Db_Expr('MAX(entity_id) as max'), 'product_id'] + ['cp', '*', null] ] ] ]; $this->selectMock->expects($this->exactly(2))->method('getPart')->willReturnMap($map); - $this->factoryMock->expects($this->never())->method('create'); - $this->model->generate('entity_id', $this->selectMock, 100); + $this->factoryMock->expects($this->once())->method('create')->with( + [ + 'select' => $this->selectMock, + 'batchSize' => 100, + 'correlationName' => 'cp', + 'rangeField' => 'entity_id', + 'rangeFieldAlias' => 'entity_id' + ] + )->willReturn($this->iteratorMock); + $this->assertEquals($this->iteratorMock, $this->model->generate('entity_id', $this->selectMock, 100)); } } -- GitLab From 41a493b36258ccfa0cb6d0c10a52d993efa071c6 Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Fri, 26 Aug 2016 16:05:14 -0500 Subject: [PATCH 702/838] MAGETWO-55871: Eliminate @escapeNotVerified in Email module - Removed module from list of exempt modules. - Corrected placement of annotation. --- .../Magento/Email/view/adminhtml/templates/template/edit.phtml | 2 +- .../Magento/Test/Php/_files/whitelist/exempt_modules/ce.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml index 66be7b59ad1..91b4300ddad 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml @@ -24,7 +24,7 @@ use Magento\Framework\App\TemplateTypesInterface; <optgroup label="<?php echo $block->escapeHtmlAttr($group) ?>"> <?php endif; ?> <?php foreach ($options as $option): ?> - <option value="<?php echo $block->escapeHtmlAttr($option['value']) ?>"<?php echo /* @noEscape */ $block->getOrigTemplateCode() == $option['value'] ? ' selected="selected"' : '' ?>><?php echo $block->escapeHtml($option['label']) ?></option> + <option value="<?php echo $block->escapeHtmlAttr($option['value']) ?>"<?php /* @noEscape */ echo $block->getOrigTemplateCode() == $option['value'] ? ' selected="selected"' : '' ?>><?php echo $block->escapeHtml($option['label']) ?></option> <?php endforeach; ?> <?php if ($group): ?> </optgroup> diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php index 18491844df0..c0316a43566 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -21,7 +21,6 @@ return [ 'Magento_ConfigurableProduct', 'Magento_CurrencySymbol', 'Magento_Downloadable', - 'Magento_Email', 'Magento_GiftMessage', 'Magento_GoogleAdwords', 'Magento_GoogleAnalytics', -- GitLab From a65e7da7047eb1d4601127b915272e84fd6a2f98 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Fri, 26 Aug 2016 16:16:44 -0500 Subject: [PATCH 703/838] MAGETWO-55589: Wrong algorithm for calculation batch size on category indexing - fixed static tests --- .../{ => Unit}/DB/Query/BatchIteratorTest.php | 29 +++++++++++++++---- .../{ => Unit}/DB/Query/GeneratorTest.php | 23 +++++++++++++-- 2 files changed, 45 insertions(+), 7 deletions(-) rename lib/internal/Magento/Framework/Test/{ => Unit}/DB/Query/BatchIteratorTest.php (94%) rename lib/internal/Magento/Framework/Test/{ => Unit}/DB/Query/GeneratorTest.php (90%) diff --git a/lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php b/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php similarity index 94% rename from lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php rename to lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php index f7adfce36a9..4ad7b8567e2 100644 --- a/lib/internal/Magento/Framework/Test/DB/Query/BatchIteratorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php @@ -31,11 +31,31 @@ class BatchIteratorTest extends \PHPUnit_Framework_TestCase */ private $connectionMock; + /** + * @var int + */ private $batchSize; + + /** + * @var string + */ private $correlationName; + + /** + * @var string + */ private $rangeField; + + /** + * @var string + */ private $rangeFieldAlias; + /** + * Setup test dependencies. + * + * @return void + */ protected function setUp() { $this->batchSize = 10; @@ -64,6 +84,7 @@ class BatchIteratorTest extends \PHPUnit_Framework_TestCase * 1. $iterator->current(); * 2. $iterator->current(); * 3. $iterator->key(); + * @return void */ public function testCurrent() { @@ -103,7 +124,7 @@ class BatchIteratorTest extends \PHPUnit_Framework_TestCase * * 1. $iterator->next() * 2. $iterator->valid(); - * + * @return void */ public function testIterations() { @@ -147,6 +168,7 @@ class BatchIteratorTest extends \PHPUnit_Framework_TestCase * 3. $iterator->next(); * 4. $iterator->current() * 5. $iterator->key() + * @return void */ public function testNext() { @@ -166,10 +188,7 @@ class BatchIteratorTest extends \PHPUnit_Framework_TestCase $this->connectionMock->expects($this->exactly(3)) ->method('fetchRow') ->with($this->wrapperSelectMock) - ->willReturn([ - 'max' => 25, - 'cnt' => 10 - ] + ->willReturn(['max' => 25, 'cnt' => 10] ); $this->assertEquals($this->selectMock, $this->model->next()); diff --git a/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php b/lib/internal/Magento/Framework/Test/Unit/DB/Query/GeneratorTest.php similarity index 90% rename from lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php rename to lib/internal/Magento/Framework/Test/Unit/DB/Query/GeneratorTest.php index 0278871d808..4be22eb14ca 100644 --- a/lib/internal/Magento/Framework/Test/DB/Query/GeneratorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/DB/Query/GeneratorTest.php @@ -32,6 +32,9 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase */ private $iteratorMock; + /** + * Setup test dependencies. + */ protected function setUp() { $this->factoryMock = $this->getMock(BatchIteratorFactory::class, [], [], '', false, false); @@ -40,6 +43,10 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase $this->model = new Generator($this->factoryMock); } + /** + * Test success generate. + * @return void + */ public function testGenerate() { $map = [ @@ -70,8 +77,11 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase } /** + * Test batch generation with invalid select object. + * * @expectedException \Magento\Framework\Exception\LocalizedException * @expectedExceptionMessage Select object must have correct "FROM" part + * @return void */ public function testGenerateWithoutFromPart() { @@ -89,7 +99,11 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase $this->model->generate('entity_id', $this->selectMock, 100); } - public function testGenerateWithInvalidRangeField() + /** + * Test generate batches with rangeField without alias. + * @return void + */ + public function testGenerateWithRangeFieldWithoutAlias() { $map = [ [ @@ -118,7 +132,12 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->iteratorMock, $this->model->generate('entity_id', $this->selectMock, 100)); } - public function testGenerateWithInvalidRangeFieldValue() + /** + * Test generate batches with wild-card. + * + * @return void + */ + public function testGenerateWithInvalidWithWildcard() { $map = [ [ -- GitLab From 2b42bb956ea8bc98ae9ff946e3e9042ce3fa0609 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Fri, 26 Aug 2016 16:22:26 -0500 Subject: [PATCH 704/838] MAGETWO-56104: Build stablization - fixed unit and static tests --- .../Test/Unit/Block/CurrencyTest.php | 27 ++++++++++++------- lib/internal/Magento/Framework/Escaper.php | 5 ++-- .../Framework/Test/Unit/EscaperTest.php | 19 ++++++++----- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php b/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php index 9abf5a87857..cfe5e2aacd3 100644 --- a/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php +++ b/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php @@ -34,16 +34,25 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase ); $this->urlBuilder->expects($this->any())->method('getUrl')->will($this->returnArgument(0)); - /** @var \Magento\Framework\View\Element\Template\Context $context */ - $context = $this->getMock( - \Magento\Framework\View\Element\Template\Context::class, - ['getUrlBuilder'], - [], - '', - false - ); + /** @var $context \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */ + $context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class) + ->disableOriginalConstructor() + ->getMock(); $context->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilder)); + $escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) + ->disableOriginalConstructor() + ->getMock(); + $escaperMock->method('escapeUrl') + ->willReturnCallback( + function ($string) { + return 'escapeUrl' . $string; + } + ); + $context->expects($this->once()) + ->method('getEscaper') + ->willReturn($escaperMock); + /** @var \Magento\Directory\Model\CurrencyFactory $currencyFactory */ $currencyFactory = $this->getMock(\Magento\Directory\Model\CurrencyFactory::class, [], [], '', false); $this->postDataHelper = $this->getMock(\Magento\Framework\Data\Helper\PostHelper::class, [], [], '', false); @@ -63,7 +72,7 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase { $expectedResult = 'post_data'; $expectedCurrencyCode = 'test'; - $switchUrl = 'directory/currency/switch'; + $switchUrl = 'escapeUrldirectory/currency/switch'; $this->postDataHelper->expects($this->once()) ->method('getPostData') diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 19ffe83fa36..7f63e485f0c 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -59,9 +59,10 @@ class Escaper $dom = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( /** - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ - function ($errorNumber, $errorString, $errorFile, $errorLine) { + function ($errorNumber, $errorString, $errorFile, $errorLine) + { throw new \Exception($errorString, $errorNumber); } ); diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 493dd4742f0..20af43aa1d7 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -87,8 +87,10 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'allowedTags' => ['span', 'b'], ], 'string data with allowed tags with attributes 3' => [ - 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', - 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'data' => 'Only registered users can write reviews. ' + . 'Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'expected' => 'Only registered users can write reviews. ' + . 'Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', 'allowedTags' => ['a'], ], 'string data with allowed tags with attributes 4' => [ @@ -109,13 +111,18 @@ class EscaperTest extends \PHPUnit_Framework_TestCase ], */ 'string data with allowed tags with attributes and not allowed tags' => [ - 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', - 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> or <a href="%2">create an account</a>', + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> ' + . 'or <a href="%2"><span id="action">create an account</span></a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> ' + . 'or <a href="%2">create an account</a>', 'allowedTags' => ['a'], ], 'string data with allowed tags with attributes and not allowed tags 2' => [ - 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a class="some-class" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', - 'expected' => 'Some test <span>text in span tag</span> text in strong tag <a class="some-class" href="http://domain.com/">Click here</a>alert(1)', + 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> ' + . '<a class="some-class" href="http://domain.com/" onclick="alert(1)">' + . 'Click here</a><script>alert(1)</script>', + 'expected' => 'Some test <span>text in span tag</span> text in strong tag ' + .'<a class="some-class" href="http://domain.com/">Click here</a>alert(1)', 'allowedTags' => ['a', 'span'], ], 'string data with allowed tags and html comment' => [ -- GitLab From f13585fe6560d7ade4e4f79bf716d66b1fab0d8c Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko <okorshenko@magento.com> Date: Fri, 26 Aug 2016 16:25:47 -0500 Subject: [PATCH 705/838] MAGETWO-55589: Wrong algorithm for calculation batch size on category indexing - fixed static tests --- .../Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php b/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php index 4ad7b8567e2..e522daf97a8 100644 --- a/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/DB/Query/BatchIteratorTest.php @@ -188,8 +188,7 @@ class BatchIteratorTest extends \PHPUnit_Framework_TestCase $this->connectionMock->expects($this->exactly(3)) ->method('fetchRow') ->with($this->wrapperSelectMock) - ->willReturn(['max' => 25, 'cnt' => 10] - ); + ->willReturn(['max' => 25, 'cnt' => 10]); $this->assertEquals($this->selectMock, $this->model->next()); $this->assertEquals(1, $this->model->key()); -- GitLab From 1e83f01cf1db7f47a949af34fd33f47b88b2020b Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Mon, 29 Aug 2016 09:08:22 +0300 Subject: [PATCH 706/838] MAGETWO-57129: Identity srvice fix --- .../Framework/DataObject/IdentityService.php | 92 +++++++++---------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/lib/internal/Magento/Framework/DataObject/IdentityService.php b/lib/internal/Magento/Framework/DataObject/IdentityService.php index c8ea4c86ab8..b16d0a249ea 100644 --- a/lib/internal/Magento/Framework/DataObject/IdentityService.php +++ b/lib/internal/Magento/Framework/DataObject/IdentityService.php @@ -1,47 +1,45 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\DataObject; - -use Ramsey\Uuid\Uuid; - -/** - * Class IdentityService - */ -class IdentityService implements IdentityGeneratorInterface -{ - /** - * @var \Ramsey\Uuid\UuidFactoryInterface - */ - private $uuidFactory; - - /** - * IdentityService constructor. - * @param \Ramsey\Uuid\UuidFactory $uuidFactory - */ - public function __construct( - \Ramsey\Uuid\UuidFactory $uuidFactory - ) { - $this->uuidFactory = $uuidFactory; - } - - /** - * @inheritDoc - */ - public function generateId() - { - $uuid = $this->uuidFactory->uuid4(); - return $uuid->toString(); - } - - /** - * @inheritDoc - */ - public function generateIdForData($data) - { - $uuid = $this->uuidFactory->uuid3(Uuid::NAMESPACE_DNS, $data); - return $uuid->toString(); - } -} +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\DataObject; + +use Ramsey\Uuid\Uuid; + +/** + * Class IdentityService + */ +class IdentityService implements IdentityGeneratorInterface +{ + /** + * @var \Ramsey\Uuid\UuidFactoryInterface + */ + private $uuidFactory; + + /** + * IdentityService constructor. + */ + public function __construct( + ) { + $this->uuidFactory = new \Ramsey\Uuid\UuidFactory(); + } + + /** + * @inheritDoc + */ + public function generateId() + { + $uuid = $this->uuidFactory->uuid4(); + return $uuid->toString(); + } + + /** + * @inheritDoc + */ + public function generateIdForData($data) + { + $uuid = $this->uuidFactory->uuid3(Uuid::NAMESPACE_DNS, $data); + return $uuid->toString(); + } +} -- GitLab From 60add52752126b002f1598e3f979f0196480d40b Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Mon, 29 Aug 2016 12:42:24 +0300 Subject: [PATCH 707/838] MAGETWO-57726: Exception is created but not thrown #6320 --- app/code/Magento/Reports/Block/Product/AbstractProduct.php | 2 +- .../Reports/Model/ResourceModel/Product/Lowstock/Collection.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Reports/Block/Product/AbstractProduct.php b/app/code/Magento/Reports/Block/Product/AbstractProduct.php index 9a142b2f982..1bd340cd718 100644 --- a/app/code/Magento/Reports/Block/Product/AbstractProduct.php +++ b/app/code/Magento/Reports/Block/Product/AbstractProduct.php @@ -90,7 +90,7 @@ abstract class AbstractProduct extends \Magento\Catalog\Block\Product\AbstractPr try { $model = $this->_indexFactory->get($this->_indexType); } catch (\InvalidArgumentException $e) { - new \Magento\Framework\Exception\LocalizedException(__('Index type is not valid')); + throw new \Magento\Framework\Exception\LocalizedException(__('Index type is not valid')); } return $model; diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php index c5fd7b09fa2..f3a142a12e5 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php @@ -249,7 +249,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection public function filterByProductType($typeFilter) { if (!is_string($typeFilter) && !is_array($typeFilter)) { - new \Magento\Framework\Exception\LocalizedException(__('The product type filter specified is incorrect.')); + throw new \Magento\Framework\Exception\LocalizedException(__('The product type filter specified is incorrect.')); } $this->addAttributeToFilter('type_id', $typeFilter); return $this; -- GitLab From df47e15f3655ef3b1ecc250f3698017813ce9d21 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 29 Aug 2016 13:48:35 +0300 Subject: [PATCH 708/838] MAGETWO-56092: Pagination is absent on Order Status grid --- .../Sales/view/adminhtml/layout/sales_order_status_index.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml index f3c7408bb6c..6929c7ad996 100644 --- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml +++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_status_index.xml @@ -15,7 +15,7 @@ <argument name="dataSource" xsi:type="object">Magento\Sales\Model\ResourceModel\Status\Collection</argument> <argument name="default_sort" xsi:type="string">state</argument> <argument name="default_dir" xsi:type="string">desc</argument> - <argument name="pager_visibility" xsi:type="string">0</argument> + <argument name="pager_visibility" xsi:type="string">1</argument> </arguments> <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="sales_order_status.grid.columnSet"> <arguments> -- GitLab From 873a1231b7ae64beda1b46e6ff06ae6fd1c3d315 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Mon, 29 Aug 2016 14:05:29 +0300 Subject: [PATCH 709/838] MAGETWO-57726: Exception is created but not thrown #6320 - Updated DocBlock --- app/code/Magento/Reports/Block/Product/AbstractProduct.php | 2 +- .../Reports/Model/ResourceModel/Product/Lowstock/Collection.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Reports/Block/Product/AbstractProduct.php b/app/code/Magento/Reports/Block/Product/AbstractProduct.php index 1bd340cd718..1fdcc297b28 100644 --- a/app/code/Magento/Reports/Block/Product/AbstractProduct.php +++ b/app/code/Magento/Reports/Block/Product/AbstractProduct.php @@ -82,7 +82,7 @@ abstract class AbstractProduct extends \Magento\Catalog\Block\Product\AbstractPr /** * Public method for retrieve Product Index model - * + * @throws \Magento\Framework\Exception\LocalizedException * @return \Magento\Reports\Model\Product\Index\AbstractIndex */ public function getModel() diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php index f3a142a12e5..9c8afd21cd6 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php @@ -244,6 +244,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection * Add filter by product type(s) * * @param array|string $typeFilter + * @throws \Magento\Framework\Exception\LocalizedException * @return $this */ public function filterByProductType($typeFilter) -- GitLab From 10b5b42e6f175fe7443421605ca0499f2a3ae357 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Mon, 29 Aug 2016 14:06:08 +0300 Subject: [PATCH 710/838] MAGETWO-56530: Magento\ConfigurableImportExport\Model\ConfigurableTest::testImportReplace integration test fail --- .../ImportExport/Model/Export/Entity/AbstractEntity.php | 8 ++++++++ .../ConfigurableImportExport/Model/ConfigurableTest.php | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php b/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php index cff55867975..f76200a576a 100644 --- a/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php +++ b/app/code/Magento/ImportExport/Model/Export/Entity/AbstractEntity.php @@ -544,4 +544,12 @@ abstract class AbstractEntity return $this; } + + /** + * Clean cached values + */ + public function __destruct() + { + self::$attrCodes = null; + } } diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php index 1b9a4d5eabc..2d355b53f6a 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableImportExport/Model/ConfigurableTest.php @@ -107,7 +107,6 @@ class ConfigurableTest extends AbstractProductExportImportTestCase */ public function testImportReplace($fixtures, $skus, $skippedAttributes = []) { - $this->markTestSkipped('MAGETWO-56530'); parent::testImportReplace($fixtures, $skus, $skippedAttributes); } } -- GitLab From 830888c64279e9072db098afb5035ff2d895841f Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 29 Aug 2016 14:28:05 +0300 Subject: [PATCH 711/838] MAGETWO-55908: Prepare PR --- .../tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Grid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Grid.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Grid.php index bd7d10a7cf0..3c2a9ed9c9b 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Grid.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Grid.php @@ -96,7 +96,7 @@ class Grid extends DataGrid $this->openFilterBlock(); $storeGroupElements = $this->_rootElement->find($this->filters['purchase_point']['selector']) - ->getElements('//option/preceding-sibling::optgroup[1]', Locator::SELECTOR_XPATH); + ->getElements('.//option/preceding-sibling::optgroup[1]', Locator::SELECTOR_XPATH); $result = []; foreach ($storeGroupElements as $storeGroupElement) { -- GitLab From c935e781e684123301687b2ae5699b17c12ae220 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 29 Aug 2016 15:17:58 +0300 Subject: [PATCH 712/838] MAGETWO-57119: Sample Data Tests fails randomly --- .../Catalog/Test/Block/Product/View.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php index 9b57ce34f4e..3134fda0d2b 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php @@ -567,12 +567,19 @@ class View extends AbstractConfigureBlock */ public function closeFullImage() { - $element = $this->browser->find($this->fullImageClose, Locator::SELECTOR_CSS); - if (!$element->isVisible()) { - $element->hover(); - $this->waitForElementVisible($this->fullImageClose); - } - $element->click(); + $this->_rootElement->waitUntil( + function () { + $this->browser->find($this->fullImage)->hover(); + + if ($this->browser->find($this->fullImageClose)->isVisible()) { + $this->browser->find($this->fullImageClose)->click(); + + return true; + } + + return null; + } + ); } /** -- GitLab From e972fc8b9bcf91825fa7c9fc68d89d49b7c25aef Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 29 Aug 2016 15:26:25 +0300 Subject: [PATCH 713/838] MAGETWO-56343: Setup tool check PHP extensions does not check for all needed extensions --- composer.json | 1 + composer.lock | 7 +++-- .../Magento/Setup/Model/PhpReadinessCheck.php | 30 ++++++++++++++++++- .../Test/Unit/Model/PhpReadinessCheckTest.php | 23 ++++++++++++-- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 8053b76a01a..a0813c84620 100644 --- a/composer.json +++ b/composer.json @@ -64,6 +64,7 @@ "ext-mbstring": "*", "ext-openssl": "*", "ext-zip": "*", + "ext-pdo_mysql": "*", "sjparkinson/static-review": "~4.1", "ramsey/uuid": "3.4" }, diff --git a/composer.lock b/composer.lock index 6fd73ef405c..4d1f23dad9b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "ad3de2234f78fd4b353ae6a1b22401fc", - "content-hash": "25dcf96ed1d8b12a25111e8b3af61317", + "hash": "c8f9e4332a46ace884514d9843021898", + "content-hash": "fa9bd2b88f3c2e1bf562c439cecca917", "packages": [ { "name": "braintree/braintree_php", @@ -4597,7 +4597,8 @@ "ext-xsl": "*", "ext-mbstring": "*", "ext-openssl": "*", - "ext-zip": "*" + "ext-zip": "*", + "ext-pdo_mysql": "*" }, "platform-dev": [] } diff --git a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php index 06e8b34471d..bcf942687a4 100644 --- a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php +++ b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php @@ -102,7 +102,8 @@ class PhpReadinessCheck $settings = array_merge( $this->checkXDebugNestedLevel(), - $this->checkPopulateRawPostSetting() + $this->checkPopulateRawPostSetting(), + $this->checkFunctionsExistence() ); foreach ($settings as $setting) { @@ -316,6 +317,33 @@ class PhpReadinessCheck return $data; } + /** + * Check whether all special functions exists + * + * @return array + */ + private function checkFunctionsExistence() + { + $data = []; + $requiredFunctions = [ + [ + 'name' => 'imagecreatefromjpeg', + 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'helpUrl' => 'http://php.net/manual/en/image.installation.php', + ], + ]; + + foreach ($requiredFunctions as $function) { + $data['missed_function_' . $function['name']] = [ + 'message' => $function['message'], + 'helpUrl' => $function['helpUrl'], + 'error' => !function_exists($function['name']), + ]; + } + + return $data; + } + /** * Normalize PHP Version * diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php index c24e1792331..785674dbae3 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php @@ -222,7 +222,12 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 'message' => $xdebugMessage, 'error' => false, ], - ] + 'missed_function_imagecreatefromjpeg' => [ + 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'helpUrl' => 'http://php.net/manual/en/image.installation.php', + 'error' => false, + ], + ], ]; if (!$this->isPhp7OrHhvm()) { $this->setUpNoPrettyVersionParser(); @@ -261,8 +266,13 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 'xdebug_max_nesting_level' => [ 'message' => $xdebugMessage, 'error' => true, - ] - ] + ], + 'missed_function_imagecreatefromjpeg' => [ + 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'helpUrl' => 'http://php.net/manual/en/image.installation.php', + 'error' => false, + ], + ], ]; if (!$this->isPhp7OrHhvm()) { $this->setUpNoPrettyVersionParser(); @@ -301,6 +311,13 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase ] ]; } + + $expected['data']['missed_function_imagecreatefromjpeg'] = [ + 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'helpUrl' => 'http://php.net/manual/en/image.installation.php', + 'error' => false, + ]; + $this->assertEquals($expected, $this->phpReadinessCheck->checkPhpSettings()); } -- GitLab From aa98f6831171a324201be19a7dfdc1695ce68639 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 29 Aug 2016 15:28:59 +0300 Subject: [PATCH 714/838] MAGETWO-56826: Notification messages area. Bug fixing activities --- .../web/css/source/_module.less | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less index e753eaa8650..bdb94e3a820 100644 --- a/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_AdminNotification/web/css/source/_module.less @@ -11,7 +11,7 @@ @message-system__border-color: @color-gray82; @message-system__border-width: .1rem; @message-system__color: @color-gray20; -@message-system-short-message__padding-vertical: 1.5rem; +@message-system-short__padding-vertical: 1.5rem; @message-system-short-wrapper__height: 5rem; // Triangle marker @@ -38,7 +38,7 @@ background: none; margin: 0 0 -3px; overflow: hidden; - padding: @message-system-short-message__padding-vertical 0 @message-system-short-message__padding-vertical 3.3rem; + padding: @message-system-short__padding-vertical 0 @message-system-short__padding-vertical 3.3rem; &:before { left: .3rem; @@ -55,7 +55,7 @@ } float: right; - padding: @message-system-short-message__padding-vertical 0 0; + padding: @message-system-short__padding-vertical 0 0; vertical-align: top; } } @@ -92,7 +92,7 @@ border-top: 0; display: none; left: -1px; - padding: 0 @indent__l @message-system-short-message__padding-vertical; + padding: 0 @indent__l @message-system-short__padding-vertical; position: absolute; right: -1px; top: 100%; @@ -106,7 +106,7 @@ .message-system-action-dropdown { .lib-button-reset(); float: right; - margin: @message-system-short-message__padding-vertical 0; + margin: @message-system-short__padding-vertical 0; position: relative; .action-toggle-triangle ( -- GitLab From 84bca457e7340dc00848e5074a23574296375c43 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Mon, 29 Aug 2016 16:12:38 +0300 Subject: [PATCH 715/838] MAGETWO-55908: Prepare PR --- .../Backend/GroupPrice/AbstractGroupPrice.php | 13 ++++++++----- .../Magento/Catalog/Model/Product/TierPrice.php | 9 --------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php index 9edb3e81c8f..3c5cef0e6ce 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/GroupPrice/AbstractGroupPrice.php @@ -339,6 +339,8 @@ abstract class AbstractGroupPrice extends Price } /** + * Perform price modification + * * @param \Magento\Catalog\Model\Product $object * @param array $data * @return array @@ -346,12 +348,13 @@ abstract class AbstractGroupPrice extends Price */ protected function modifyPriceData($object, $data) { - foreach ($data as $k => $v) { - if (isset($v['price']) && $v['price'] > 0) { - $data[$k]['website_price'] = $v['price']; + /** @var array $priceItem */ + foreach ($data as $key => $priceItem) { + if (isset($priceItem['price']) && $priceItem['price'] > 0) { + $data[$key]['website_price'] = $priceItem['price']; } - if ($v['all_groups']) { - $data[$k]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId(); + if ($priceItem['all_groups']) { + $data[$key]['cust_group'] = $this->_groupManagement->getAllCustomersGroup()->getId(); } } return $data; diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php index 985853314c4..e40b2463135 100644 --- a/app/code/Magento/Catalog/Model/Product/TierPrice.php +++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php @@ -1,14 +1,11 @@ <?php /** - * * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Model\Product; -use Magento\Framework\App\ObjectManager; - /** * @codeCoverageIgnore */ @@ -83,12 +80,6 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme */ public function getExtensionAttributes() { - if (empty($this->_getExtensionAttributes())) { - $this->setExtensionAttributes( - ObjectManager::getInstance()->get(\Magento\Framework\Api\ExtensionAttributesFactory::class) - ->create(\Magento\Catalog\Api\Data\ProductTierPriceInterface::class) - ); - } return $this->_getExtensionAttributes(); } -- GitLab From c84bb00ab00e738efe22763d22846eb081e50606 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Mon, 29 Aug 2016 16:49:55 +0300 Subject: [PATCH 716/838] MAGETWO-56343: Setup tool check PHP extensions does not check for all needed extensions --- setup/src/Magento/Setup/Model/PhpReadinessCheck.php | 2 +- .../Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php index bcf942687a4..74b2afd1419 100644 --- a/setup/src/Magento/Setup/Model/PhpReadinessCheck.php +++ b/setup/src/Magento/Setup/Model/PhpReadinessCheck.php @@ -328,7 +328,7 @@ class PhpReadinessCheck $requiredFunctions = [ [ 'name' => 'imagecreatefromjpeg', - 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'message' => 'You must have installed GD library with --with-jpeg-dir=DIR option.', 'helpUrl' => 'http://php.net/manual/en/image.installation.php', ], ]; diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php index 785674dbae3..a77bd46c79f 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php @@ -223,7 +223,7 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 'error' => false, ], 'missed_function_imagecreatefromjpeg' => [ - 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'message' => 'You must have installed GD library with --with-jpeg-dir=DIR option.', 'helpUrl' => 'http://php.net/manual/en/image.installation.php', 'error' => false, ], @@ -268,7 +268,7 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 'error' => true, ], 'missed_function_imagecreatefromjpeg' => [ - 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'message' => 'You must have installed GD library with --with-jpeg-dir=DIR option.', 'helpUrl' => 'http://php.net/manual/en/image.installation.php', 'error' => false, ], @@ -313,7 +313,7 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase } $expected['data']['missed_function_imagecreatefromjpeg'] = [ - 'message' => 'You must have installed GD library wuth --with-jpeg-dir=DIR option.', + 'message' => 'You must have installed GD library with --with-jpeg-dir=DIR option.', 'helpUrl' => 'http://php.net/manual/en/image.installation.php', 'error' => false, ]; -- GitLab From 2c67f26f5d7a9a150928024e8476912ee26694ed Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 29 Aug 2016 09:22:22 -0500 Subject: [PATCH 717/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Escaping translation --- .../Magento/Store/view/frontend/templates/switch/flags.phtml | 4 ++-- .../Store/view/frontend/templates/switch/languages.phtml | 2 +- .../Magento/Store/view/frontend/templates/switch/stores.phtml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml index f2e6220bdef..53d4428172a 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml @@ -9,8 +9,8 @@ ?> <?php if (count($block->getStores())>1): ?> <div class="form-language"> - <label for="select-language"><?php /* @escapeNotVerified */ echo __('Your Language:') ?></label> - <select id="select-language" title="<?php /* @escapeNotVerified */ echo __('Your Language') ?>" onchange="window.location.href=this.value" class="flags"> + <label for="select-language"><?php echo $block->escapeHtml(__('Your Language:')) ?></label> + <select id="select-language" title="<?php echo $block->escapeHtml(__('Your Language')) ?>" onchange="window.location.href=this.value" class="flags"> <?php foreach ($block->getStores() as $_lang): ?> <?php $_selected = ($_lang->getId() == $block->getCurrentStoreId()) ? ' selected="selected"' : '' ?> <option value="<?php /* @escapeNotVerified */ echo $_lang->getCurrentUrl() ?>" style="background-image:url('<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif') ?>');"<?php /* @escapeNotVerified */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> 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 6d77072e666..5f32021de34 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -16,7 +16,7 @@ <?php if (count($block->getStores())>1): ?> <?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> <div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php /* @escapeNotVerified */ echo $id?>"> - <strong class="label switcher-label"><span><?php /* @escapeNotVerified */ echo __('Language') ?></span></strong> + <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Language')) ?></span></strong> <div class="actions dropdown options switcher-options"> <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php /* @escapeNotVerified */ echo $id?>"> <strong class="view-<?php echo $block->escapeHtml($block->getCurrentStoreCode()) ?>"> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml index e96ea34cdee..d19797285b7 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml @@ -16,7 +16,7 @@ ?> <?php if (count($block->getGroups())>1): ?> <div class="switcher store switcher-store" id="switcher-store"> - <strong class="label switcher-label"><span><?php /* @escapeNotVerified */ echo __('Select Store') ?></span></strong> + <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Select Store')) ?></span></strong> <div class="actions dropdown options switcher-options"> <?php foreach ($block->getGroups() as $_group): ?> <?php if ($_group->getId() == $block->getCurrentGroupId()): ?> -- GitLab From b566e2fc25a86ba06089b12b27ded628995fb4f2 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Mon, 29 Aug 2016 13:59:33 -0500 Subject: [PATCH 718/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Escaping translation --- .../view/adminhtml/templates/translate_inline.phtml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml index ab82bd0279a..08b64dc3a69 100644 --- a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml @@ -8,8 +8,8 @@ ?> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('prototype/windows/themes/default.css') ?>"/> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('mage/translate-inline.css') ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> <script id="translate-inline-icon" type="text/x-magento-template"> <img src="<%- data.img %>" height="16" width="16" class="translate-edit-icon"> @@ -53,8 +53,7 @@ <% } %> </script> -<div data-role="translate-dialog" - data-mage-init='{"translateInline":{"ajaxUrl":"<?php /* @escapeNotVerified */ echo $block->getAjaxUrl() ?>"},"loader":{}}'></div> +<div data-role="translate-dialog" data-mage-init='{"translateInline":{"ajaxUrl":"<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>"},"loader":{}}'></div> <script> require([ "jquery", @@ -63,7 +62,7 @@ require([ ], function($){ $('body').editTrigger( { - img: '<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Theme::fam_book_open.png') ?>', + img: '<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Theme::fam_book_open.png')) ?>', alwaysShown: true, singleElement: false } -- GitLab From bf8b25d63e06901e6c07473356d0fc9450c2a6b4 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Mon, 29 Aug 2016 14:20:06 -0500 Subject: [PATCH 719/838] MAGETWO-56104: Build stablization - fixed code style --- lib/internal/Magento/Framework/Escaper.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 7f63e485f0c..c6734ad31de 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -58,11 +58,7 @@ class Escaper $wrapperElementId = uniqid(); $dom = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( - /** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ - function ($errorNumber, $errorString, $errorFile, $errorLine) - { + function ($errorNumber, $errorString) { throw new \Exception($errorString, $errorNumber); } ); @@ -75,8 +71,10 @@ class Escaper restore_error_handler(); $xpath = new \DOMXPath($dom); - $nodes = $xpath->query('//node()[name() != \'' - . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) . '\']'); + $nodes = $xpath->query( + '//node()[name() != \'' + . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) . '\']' + ); foreach ($nodes as $node) { if ($node->nodeName != '#text' && $node->nodeName != '#comment') { $node->parentNode->replaceChild($dom->createTextNode($node->textContent), $node); -- GitLab From 5b7cc1e5f558d05a1a8b09c89c8f05db949b0e36 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 30 Aug 2016 10:16:43 +0300 Subject: [PATCH 720/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../Checkout/CustomerData/DefaultItem.php | 1 + .../Model/Product/Type/Configurable.php | 2 +- ...ckout_cart_configure_type_configurable.xml | 3 + .../web/js/configurable-customer-data.js | 115 ++++++++++++++++++ .../view/frontend/web/js/configurable.js | 2 + .../view/frontend/web/js/swatch-renderer.js | 17 +++ 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js diff --git a/app/code/Magento/Checkout/CustomerData/DefaultItem.php b/app/code/Magento/Checkout/CustomerData/DefaultItem.php index 4cdc4c59b97..9c35265d03f 100644 --- a/app/code/Magento/Checkout/CustomerData/DefaultItem.php +++ b/app/code/Magento/Checkout/CustomerData/DefaultItem.php @@ -70,6 +70,7 @@ class DefaultItem extends AbstractItem 'item_id' => $this->item->getId(), 'configure_url' => $this->getConfigureUrl(), 'is_visible_in_site_visibility' => $this->item->getProduct()->isVisibleInSiteVisibility(), + 'product_id' => $this->item->getProduct()->getId(), 'product_name' => $this->item->getProduct()->getName(), 'product_sku' => $this->item->getProduct()->getSku(), 'product_url' => $this->getProductUrl(), diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 127940d7586..08666caa775 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -900,7 +900,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType $value = ''; } - $attributes[] = ['label' => $label, 'value' => $value]; + $attributes[] = ['label' => $label, 'value' => $value, 'attributeId' => $attributeId, 'attributeValue' => $attributeValue]; } } } diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml b/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml index bd61a5d5db5..e34b4a99494 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml +++ b/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml @@ -8,4 +8,7 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <update handle="catalog_product_view_type_configurable"/> <body/> + <head> + <link src="Magento_ConfigurableProduct::js/configurable-customer-data.js"/> + </head> </page> diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js new file mode 100644 index 00000000000..856722657e6 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js @@ -0,0 +1,115 @@ +require([ + 'jquery', + 'Magento_Customer/js/customer-data' +], function ($, customerData) { + 'use strict'; + + var selectors = { + configurableWidget: 'mageConfigurable', + swatchWidget: 'mageSwatchRenderer', + formSelector: '#product_addtocart_form', + swatchSelector: '.swatch-opt', + productIdSelector: '#product_addtocart_form [name="product"]' + }, + configurableWidget, + swatchWidget, + productOptions, + cartData = customerData.get('cart'), + productId = $(selectors.productIdSelector).val(), + selectOption, + updateConfigurableOptions, + updateSwatchOptions, + setProductOptions; + + /* + if (!$(selectors.formSelector).data(selectors.configurableWidget)) { + return; + }*/ + + /** + * Sets specific configurable attribute's selected value + * + * @param {HTMLElement} elem - configurable attribute + * @param {String} value - configurable attribute's selected value + */ + selectOption = function (elem, value) { + elem = $(elem); + + if (value && elem.val() !== value) { + elem.val(value); + } + }; + + /** + * Sets all configurable attribute's selected values + */ + updateConfigurableOptions = function () { + configurableWidget = $(selectors.formSelector).data(selectors.configurableWidget); + if (!configurableWidget) { + return; + } + + configurableWidget.options.values = productOptions || {}; + configurableWidget._configureForValues(); + +/* + $(selectors.superSelector).each(function () { + currentAttributeId = (selectors.attributeIdRegex.exec((this.attributes[selectors.attributeIdSelector] || {}).value) || [])[1]; + + if (productOptions && currentAttributeId) { + selectOption(this, productOptions[currentAttributeId]); + } + });*/ + }; + + /** + * Sets all configurable swatch attribute's selected values + */ + updateSwatchOptions = function () { + if (!productOptions) { + setProductOptions(cartData()); + } + if (!productOptions) { + return; + } + + swatchWidget = $(selectors.swatchSelector).data(selectors.swatchWidget); + if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) { + return; + } + swatchWidget._EmulateSelectedByAttributeId(productOptions); + }; + + /** + * set productOptions according to cart data from customer-data + * + * @param {Object} data - cart data from customer-data + */ + setProductOptions = function (data) { + if (!(data && data.items && data.items.length && productId)) { + return; + } + productOptions = data.items.find(function (item) { + return item['product_id'] === productId; + }); + productOptions = productOptions && productOptions.options && + productOptions.options.reduce(function (obj, val) { + obj[val.attributeId] = val.attributeValue; + + return obj; + }, {}); + } + + cartData.subscribe(function (updateCartData) { + setProductOptions(updateCartData); + updateConfigurableOptions(); + updateSwatchOptions(); + }); + $(selectors.formSelector).on('configurable.initialized', function () { + setProductOptions(cartData()); + updateConfigurableOptions(); + }); + $(selectors.formSelector).on('swatch.initialized', function () { + updateSwatchOptions(); + }); +}); diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index d38e2760f1d..bd0314aacf7 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -53,6 +53,8 @@ define([ // Setup/configure values to inputs this._configureForValues(); + + $(this.element).trigger('configurable.initialized'); }, /** diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index dfd4b2bb2da..19fcfd38374 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -210,6 +210,7 @@ define([ if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') { this._sortAttributes(); this._RenderControls(); + $(this.element).trigger('swatch.initialized'); } else { console.log('SwatchRenderer: No input data received'); } @@ -951,6 +952,22 @@ define([ }, this)); }, + /** + * Emulate mouse click on all swatches that should be selected + * @param {Object} [selectedAttributes] + * @private + */ + _EmulateSelectedByAttributeId: function (selectedAttributes) { + $.each(selectedAttributes, $.proxy(function (attributeId, optionId) { + var elem = this.element.find('.' + this.options.classes.attributeClass + + '[attribute-id="' + attributeId + '"] [option-id="' + optionId + '"]'); + debugger; + if (!elem.hasClass('selected')) { + elem.trigger('click'); + } + }, this)); + }, + /** * Get default options values settings with either URL query parameters * @private -- GitLab From 5bfc781f710941692ef6847ddee796089f8f3324 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 30 Aug 2016 10:29:20 +0300 Subject: [PATCH 721/838] MAGETWO-56473: Can't run B2B functional tests for logic with asynchronous operations --- .../Magento/Mtf/Util/Command/Cli/Queue.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Queue.php diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Queue.php b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Queue.php new file mode 100644 index 00000000000..bd85ea40fb4 --- /dev/null +++ b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Queue.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Mtf\Util\Command\Cli; + +/** + * Class Queue + */ +class Queue extends \Magento\Mtf\Util\Command\Cli +{ + /** + * Starts consumer + * + * @param string $consumer + */ + public function run($consumer) + { + parent::execute('queue:consumers:start ' . $consumer . ' > /dev/null &'); + } +} -- GitLab From d4d99d3041b75489d290164f5cacddbef8916d8c Mon Sep 17 00:00:00 2001 From: Roman Liukshyn <rliukshyn@magento.com> Date: Tue, 30 Aug 2016 11:15:02 +0300 Subject: [PATCH 722/838] MAGETWO-57228: Update BIN ranges for Discover Network and Mastercard for server validation --- app/code/Magento/Payment/Model/Method/Cc.php | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Payment/Model/Method/Cc.php b/app/code/Magento/Payment/Model/Method/Cc.php index f66db9fb49d..327dd1dee51 100644 --- a/app/code/Magento/Payment/Model/Method/Cc.php +++ b/app/code/Magento/Payment/Model/Method/Cc.php @@ -134,21 +134,16 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod // Visa 'VI' => '/^4[0-9]{12}([0-9]{3})?$/', // Master Card - 'MC' => '/^5[1-5][0-9]{14}$/', + 'MC' => '/^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/', // American Express 'AE' => '/^3[47][0-9]{13}$/', // Discover - 'DI' => '/^(30[0-5][0-9]{13}|3095[0-9]{12}|35(2[8-9][0-9]{12}|[3-8][0-9]{13})' . - '|36[0-9]{12}|3[8-9][0-9]{14}|6011(0[0-9]{11}|[2-4][0-9]{11}|74[0-9]{10}|7[7-9][0-9]{10}' . - '|8[6-9][0-9]{10}|9[0-9]{11})|62(2(12[6-9][0-9]{10}|1[3-9][0-9]{11}|[2-8][0-9]{12}' . - '|9[0-1][0-9]{11}|92[0-5][0-9]{10})|[4-6][0-9]{13}|8[2-8][0-9]{12})|6(4[4-9][0-9]{13}' . - '|5[0-9]{14}))$/', + 'DI' => '/^(6011((0|9|[2-4])[0-9]{11,14}|(74|7[7-9]|8[6-9])[0-9]{10,13})|6(4[4-9][0-9]{13,16}|5[0-9]{14,17}))/', + 'DN' => '/^3(0[0-5][0-9]{13,16}|095[0-9]{12,15}|(6|[8-9])[0-9]{14,17})/', + // UnionPay + 'UN' => '/^622(1(2[6-9][0-9]{10,13}|[3-9][0-9]{11,14})|[3-8][0-9]{12,15}|9([[0-1][0-9]{11,14}|2[0-5][0-9]{10,13}))|62[4-6][0-9]{13,16}|628[2-8][0-9]{12,15}/', // JCB - 'JCB' => '/^(30[0-5][0-9]{13}|3095[0-9]{12}|35(2[8-9][0-9]{12}|[3-8][0-9]{13})|36[0-9]{12}' . - '|3[8-9][0-9]{14}|6011(0[0-9]{11}|[2-4][0-9]{11}|74[0-9]{10}|7[7-9][0-9]{10}' . - '|8[6-9][0-9]{10}|9[0-9]{11})|62(2(12[6-9][0-9]{10}|1[3-9][0-9]{11}|[2-8][0-9]{12}' . - '|9[0-1][0-9]{11}|92[0-5][0-9]{10})|[4-6][0-9]{13}|8[2-8][0-9]{12})|6(4[4-9][0-9]{13}' . - '|5[0-9]{14}))$/', + 'JCB' => '/^35(2[8-9][0-9]{12,15}|[3-8][0-9]{13,16})/', 'MI' => '/^(5(0|[6-9])|63|67(?!59|6770|6774))\d*$/', 'MD' => '/^(6759(?!24|38|40|6[3-9]|70|76)|676770|676774)\d*$/', ]; @@ -215,6 +210,8 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod 'MC' => '/^[0-9]{3}$/', 'AE' => '/^[0-9]{4}$/', 'DI' => '/^[0-9]{3}$/', + 'DN' => '/^[0-9]{3}$/', + 'UN' => '/^[0-9]{3}$/', 'SS' => '/^[0-9]{3,4}$/', 'SM' => '/^[0-9]{3,4}$/', 'SO' => '/^[0-9]{3,4}$/', -- GitLab From 7fb9c0b5c7d2c977d064bf2cb43e7c32fdd71687 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 30 Aug 2016 12:17:50 +0300 Subject: [PATCH 723/838] MAGETWO-55908: Prepare PR --- .../Catalog/Api/ProductTierPriceManagementInterface.php | 1 + .../Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php | 2 +- .../Attribute/Source/GroupSourceLoggedInOnlyInterface.php | 4 ++-- .../Customer/Model/Customer/Source/GroupSourceInterface.php | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php b/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php index d587aec01cc..f02c3afa5ae 100644 --- a/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php +++ b/app/code/Magento/Catalog/Api/ProductTierPriceManagementInterface.php @@ -8,6 +8,7 @@ namespace Magento\Catalog\Api; /** * @api + * @deprecated use ScopedProductTierPriceManagementInterface instead */ interface ProductTierPriceManagementInterface { diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 071bc8d7967..c42efd5a1e6 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -650,7 +650,7 @@ class AdvancedPricing extends AbstractModifier /** * Retrieve store * - * @return \Magento\Store\Model\Store + * @return \Magento\Store\Api\Data\StoreInterface */ private function getStore() { diff --git a/app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php b/app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php index 93df78a1be1..5570b4073df 100644 --- a/app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Attribute/Source/GroupSourceLoggedInOnlyInterface.php @@ -6,9 +6,9 @@ namespace Magento\Customer\Model\Customer\Attribute\Source; -use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; +use \Magento\Framework\Data\OptionSourceInterface; -interface GroupSourceLoggedInOnlyInterface extends OptionArrayInterface +interface GroupSourceLoggedInOnlyInterface extends OptionSourceInterface { } diff --git a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php index d180ad4d491..c044740dc35 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php +++ b/app/code/Magento/Customer/Model/Customer/Source/GroupSourceInterface.php @@ -5,9 +5,9 @@ */ namespace Magento\Customer\Model\Customer\Source; -use Magento\Framework\Option\ArrayInterface as OptionArrayInterface; +use Magento\Framework\Data\OptionSourceInterface; -interface GroupSourceInterface extends OptionArrayInterface +interface GroupSourceInterface extends OptionSourceInterface { } -- GitLab From be08f1a08d368c07701591d0f5d8e0df27f97275 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Tue, 30 Aug 2016 12:58:44 +0300 Subject: [PATCH 724/838] MAGETWO-55757: Magento 2 does not work on Apache php-fpm environment --- .user.ini | 4 ++++ pub/.user.ini | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 .user.ini create mode 100644 pub/.user.ini diff --git a/.user.ini b/.user.ini new file mode 100644 index 00000000000..8c0b765e055 --- /dev/null +++ b/.user.ini @@ -0,0 +1,4 @@ +memory_limit = 768M +max_execution_time = 18000 +session.auto_start = off +suhosin.session.cryptua = off \ No newline at end of file diff --git a/pub/.user.ini b/pub/.user.ini new file mode 100644 index 00000000000..8c0b765e055 --- /dev/null +++ b/pub/.user.ini @@ -0,0 +1,4 @@ +memory_limit = 768M +max_execution_time = 18000 +session.auto_start = off +suhosin.session.cryptua = off \ No newline at end of file -- GitLab From 2db5aa15722307fb6ad703627933224f5f74bbe3 Mon Sep 17 00:00:00 2001 From: Andrii Dimov <adimov@magento.com> Date: Thu, 25 Aug 2016 14:51:08 +0300 Subject: [PATCH 725/838] MAGETWO-54718: [GitHub] Exception thrown where no Product Image file found #5184 #5497 #5871 --- .../Product/Helper/Form/Gallery/Content.php | 29 ++------------ .../Helper/Form/Gallery/ContentTest.php | 39 ++++--------------- 2 files changed, 11 insertions(+), 57 deletions(-) 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 262ba8cccc2..fa863176952 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 @@ -40,11 +40,6 @@ class Content extends \Magento\Backend\Block\Widget */ private $imageHelper; - /** - * @var \Magento\Framework\View\Asset\Repository - */ - private $assetRepo; - /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder @@ -139,7 +134,7 @@ class Content extends \Magento\Backend\Block\Widget is_array($value['images']) && count($value['images']) ) { - $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); + $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); $images = $this->sortImagesByPosition($value['images']); foreach ($images as &$image) { $image['url'] = $this->_mediaConfig->getMediaUrl($image['file']); @@ -147,12 +142,8 @@ class Content extends \Magento\Backend\Block\Widget $fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file'])); $image['size'] = $fileHandler['size']; } catch (FileSystemException $e) { - $staticDir = $this->_filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW); - $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('thumbnail'); - $fileHandler = $staticDir->stat( - $this->getAssetRepo()->createAsset($this->getImageHelper()->getPlaceholder('thumbnail'))->getPath() - ); - $image['size'] = $fileHandler['size']; + $image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('small_image'); + $image['size'] = 0; $this->_logger->warning($e); } } @@ -261,18 +252,4 @@ class Content extends \Magento\Backend\Block\Widget } return $this->imageHelper; } - - /** - * @return \Magento\Framework\View\Asset\Repository - * @deprecated - */ - private function getAssetRepo() - { - if ($this->assetRepo === null) { - $this->assetRepo = \Magento\Framework\App\ObjectManager::getInstance() - ->get('\Magento\Framework\View\Asset\Repository'); - } - - return $this->assetRepo; - } } diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php index 33faf5963c9..0ec8e533575 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Helper/Form/Gallery/ContentTest.php @@ -46,11 +46,6 @@ class ContentTest extends \PHPUnit_Framework_TestCase */ protected $imageHelper; - /** - * @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject - */ - protected $assetRepo; - /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ @@ -171,30 +166,17 @@ class ContentTest extends \PHPUnit_Framework_TestCase { $this->imageHelper = $this->getMockBuilder('Magento\Catalog\Helper\Image') ->disableOriginalConstructor() - ->setMethods(['getDefaultPlaceholderUrl', 'getPlaceholder']) - ->getMock(); - - $this->assetRepo = $this->getMockBuilder('Magento\Framework\View\Asset\Repository') - ->disableOriginalConstructor() - ->setMethods(['createAsset', 'getPath']) + ->setMethods(['getDefaultPlaceholderUrl']) ->getMock(); $this->objectManager->setBackwardCompatibleProperty( $this->content, 'imageHelper', - $this->imageHelper - ); - - $this->objectManager->setBackwardCompatibleProperty( - $this->content, - 'assetRepo', - $this->assetRepo + $this->imageHelper ); $placeholderUrl = 'url_to_the_placeholder/placeholder.jpg'; - $sizePlaceholder = ['size' => 399659]; - $imagesResult = [ [ 'value_id' => '2', @@ -202,7 +184,7 @@ class ContentTest extends \PHPUnit_Framework_TestCase 'media_type' => 'image', 'position' => '0', 'url' => 'url_to_the_placeholder/placeholder.jpg', - 'size' => 399659 + 'size' => 0 ], [ 'value_id' => '1', @@ -210,7 +192,7 @@ class ContentTest extends \PHPUnit_Framework_TestCase 'media_type' => 'image', 'position' => '1', 'url' => 'url_to_the_placeholder/placeholder.jpg', - 'size' => 399659 + 'size' => 0 ] ]; @@ -238,20 +220,15 @@ class ContentTest extends \PHPUnit_Framework_TestCase $this->mediaConfigMock->expects($this->any())->method('getMediaPath'); $this->readMock->expects($this->any())->method('stat')->willReturnOnConsecutiveCalls( $this->throwException( - new \Magento\Framework\Exception\FileSystemException(new \Magento\Framework\Phrase('test')) + new \Magento\Framework\Exception\FileSystemException(new Phrase('test')) ), - $sizePlaceholder, $this->throwException( - new \Magento\Framework\Exception\FileSystemException(new \Magento\Framework\Phrase('test')) - ), - $sizePlaceholder + new \Magento\Framework\Exception\FileSystemException(new Phrase('test')) + ) ); $this->imageHelper->expects($this->any())->method('getDefaultPlaceholderUrl')->willReturn($placeholderUrl); - $this->imageHelper->expects($this->any())->method('getPlaceholder'); - $this->assetRepo->expects($this->any())->method('createAsset')->willReturnSelf(); - $this->assetRepo->expects($this->any())->method('getPath'); $this->jsonEncoderMock->expects($this->once())->method('encode')->willReturnCallback('json_encode'); $this->assertSame(json_encode($imagesResult), $this->content->getImagesJson()); - } + } } -- GitLab From e8066da501a51b59917608b004d55b6059dbdbdc Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 30 Aug 2016 13:49:49 +0300 Subject: [PATCH 726/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../Model/Product/Type/Configurable.php | 3 +- .../Model/Product/Type/ConfigurableTest.php | 3 +- .../web/js/configurable-customer-data.js | 80 +++++++------------ .../view/frontend/web/js/swatch-renderer.js | 16 +++- 4 files changed, 45 insertions(+), 57 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 08666caa775..8c1bf07a172 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -900,7 +900,8 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType $value = ''; } - $attributes[] = ['label' => $label, 'value' => $value, 'attributeId' => $attributeId, 'attributeValue' => $attributeValue]; + $attributes[] = ['label' => $label, 'value' => $value, + 'option_id' => $attributeId, 'option_value' => $attributeValue]; } } } 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 21730cf65f0..4a49cb0b5e7 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 @@ -660,7 +660,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->_model->getSelectedAttributesInfo($productMock), - [['label' => 'attr_store_label', 'value' => '']] + [['label' => 'attr_store_label', 'value' => '', + 'option_id' => '1', 'option_value' => '']] ); } diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js index 856722657e6..9685af513ed 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js @@ -14,102 +14,80 @@ require([ configurableWidget, swatchWidget, productOptions, + tempProductOptions, cartData = customerData.get('cart'), productId = $(selectors.productIdSelector).val(), - selectOption, updateConfigurableOptions, updateSwatchOptions, setProductOptions; - /* - if (!$(selectors.formSelector).data(selectors.configurableWidget)) { - return; - }*/ - /** - * Sets specific configurable attribute's selected value - * - * @param {HTMLElement} elem - configurable attribute - * @param {String} value - configurable attribute's selected value - */ - selectOption = function (elem, value) { - elem = $(elem); - - if (value && elem.val() !== value) { - elem.val(value); - } - }; /** * Sets all configurable attribute's selected values */ updateConfigurableOptions = function () { configurableWidget = $(selectors.formSelector).data(selectors.configurableWidget); + if (!configurableWidget) { return; } - configurableWidget.options.values = productOptions || {}; configurableWidget._configureForValues(); - -/* - $(selectors.superSelector).each(function () { - currentAttributeId = (selectors.attributeIdRegex.exec((this.attributes[selectors.attributeIdSelector] || {}).value) || [])[1]; - - if (productOptions && currentAttributeId) { - selectOption(this, productOptions[currentAttributeId]); - } - });*/ }; /** * Sets all configurable swatch attribute's selected values */ updateSwatchOptions = function () { - if (!productOptions) { - setProductOptions(cartData()); - } - if (!productOptions) { - return; - } + swatchWidget = $(selectors.swatchSelector).data(selectors.swatchWidget); - swatchWidget = $(selectors.swatchSelector).data(selectors.swatchWidget); - if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) { - return; - } - swatchWidget._EmulateSelectedByAttributeId(productOptions); + if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) { + return; + } + swatchWidget._EmulateSelectedByAttributeId(productOptions); }; /** * set productOptions according to cart data from customer-data * * @param {Object} data - cart data from customer-data + * @returns {Boolean} - whether the new options differ from previous */ setProductOptions = function (data) { if (!(data && data.items && data.items.length && productId)) { return; } - productOptions = data.items.find(function (item) { - return item['product_id'] === productId; + tempProductOptions = data.items.find(function (item) { + return item['product_id'] === productId; }); - productOptions = productOptions && productOptions.options && - productOptions.options.reduce(function (obj, val) { - obj[val.attributeId] = val.attributeValue; + tempProductOptions = tempProductOptions && tempProductOptions.options && + tempProductOptions.options.reduce(function (obj, val) { + obj[val['option_id']] = val['option_value']; return obj; }, {}); - } + + if (JSON.stringify(productOptions || {}) === JSON.stringify(tempProductOptions || {}) ) { + return false; + } + + productOptions = tempProductOptions; + return true; + }; cartData.subscribe(function (updateCartData) { - setProductOptions(updateCartData); - updateConfigurableOptions(); - updateSwatchOptions(); + if (setProductOptions(updateCartData)) { + updateConfigurableOptions(); + updateSwatchOptions(); + } }); $(selectors.formSelector).on('configurable.initialized', function () { - setProductOptions(cartData()); - updateConfigurableOptions(); + setProductOptions(cartData()); + updateConfigurableOptions(); }); $(selectors.formSelector).on('swatch.initialized', function () { - updateSwatchOptions(); + setProductOptions(cartData()); + updateSwatchOptions(); }); }); diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 19fcfd38374..e748f0edb6d 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -953,16 +953,24 @@ define([ }, /** - * Emulate mouse click on all swatches that should be selected + * Emulate mouse click or selection change on all swatches that should be selected * @param {Object} [selectedAttributes] * @private */ _EmulateSelectedByAttributeId: function (selectedAttributes) { $.each(selectedAttributes, $.proxy(function (attributeId, optionId) { var elem = this.element.find('.' + this.options.classes.attributeClass + - '[attribute-id="' + attributeId + '"] [option-id="' + optionId + '"]'); - debugger; - if (!elem.hasClass('selected')) { + '[attribute-id="' + attributeId + '"] [option-id="' + optionId + '"]'), + parentInput = elem.parent(); + + if (elem.hasClass('selected')) { + return; + } + + if (parentInput.hasClass(this.options.classes.selectClass)) { + parentInput.val(optionId); + parentInput.trigger('change'); + } else { elem.trigger('click'); } }, this)); -- GitLab From 70b8bfcd5be00d43c4b220af7b2b10f8edc52032 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Tue, 30 Aug 2016 13:53:01 +0300 Subject: [PATCH 727/838] MAGETWO-55908: Prepare PR --- .../Config/Source/Group/MultiselectTest.php | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php new file mode 100644 index 00000000000..899572a500e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Config/Source/Group/MultiselectTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Model\Config\Source\Group; + +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Class \Magento\Customer\Model\Config\Source\Group\Multiselect + */ +class MultiselectTest extends \PHPUnit_Framework_TestCase +{ + public function testToOptionArray() + { + /** @var Multiselect $multiselect */ + $multiselect = Bootstrap::getObjectManager()->get( + \Magento\Customer\Model\Config\Source\Group\Multiselect::class + ); + + $options = $multiselect->toOptionArray(); + $optionsToCompare = []; + foreach ($options as $option) { + if (is_array($option['value'])) { + $optionsToCompare = array_merge($optionsToCompare, $option['value']); + } else { + $optionsToCompare[] = $option; + } + } + sort($optionsToCompare); + $this->assertEquals( + [ + ['value' => 1, 'label' => 'General'], + ['value' => 2, 'label' => 'Wholesale'], + ['value' => 3, 'label' => 'Retailer'], + ], + $optionsToCompare + ); + } +} -- GitLab From 0f1137ec0f061ae2f7cdfcc61a2dee5a5ebfbc77 Mon Sep 17 00:00:00 2001 From: Oleh Posyniak <oposyniak@magento.com> Date: Tue, 30 Aug 2016 14:46:54 +0300 Subject: [PATCH 728/838] MAGETWO-53549: [Github][PR] Replace fabpot/php-cs-fixer with friendsofphp/php-cs-fixer #4791 --- composer.lock | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 4d1f23dad9b..d842cdec858 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "c8f9e4332a46ace884514d9843021898", - "content-hash": "fa9bd2b88f3c2e1bf562c439cecca917", + "hash": "1c5d7ca4fa68bea1ab7490cb8ac62342", + "content-hash": "ecfa548096f500a6a98a5fc41c21e53b", "packages": [ { "name": "braintree/braintree_php", @@ -3232,7 +3232,7 @@ "time": "2015-06-14 21:17:01" }, { - "name": "fabpot/php-cs-fixer", + "name": "friendsofphp/php-cs-fixer", "version": "v1.12.0", "source": { "type": "git", @@ -3287,7 +3287,6 @@ } ], "description": "A tool to automatically fix PHP code style", - "abandoned": "friendsofphp/php-cs-fixer", "time": "2016-08-17 00:17:27" }, { -- GitLab From 9c63782d621cfb3402d363944d6d782a0da2a008 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 30 Aug 2016 15:32:29 +0300 Subject: [PATCH 729/838] MAGETWO-57140: CLONE - [GitHub] Wrong initialization sequence in mage.priceBox widget (price-box.js) #6117 FOR 2.2 --- app/code/Magento/Catalog/view/base/web/js/price-box.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index b095d24cf48..8f18871de82 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -199,10 +199,7 @@ define([ _setDefaultsFromPriceConfig: function _setDefaultsFromPriceConfig() { var config = this.options.priceConfig; - if (config) { - if (+config.productId !== +this.options.productId) { - return; - } + if (config && config.prices) { this.options.prices = config.prices; } } -- GitLab From 8199acd63966e3e79957f9eb0967a3f68ddcef39 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Tue, 30 Aug 2016 15:43:08 +0300 Subject: [PATCH 730/838] MAGETWO-52449: Issues with minicart in multiwebsite --- .../Magento/Checkout/view/frontend/web/js/view/minicart.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 602451d90cc..0e5e1dc35bf 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -97,8 +97,7 @@ define([ addToCartCalls++; self.isLoading(true); }); - - if (cartData().websiteId !== window.checkout.websiteId) { + if (cartData().website_id !== window.checkout.websiteId) { customerData.reload(['cart'], false); } -- GitLab From 71edd8865080cb797287e742c5d952222299e266 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 30 Aug 2016 15:43:27 +0300 Subject: [PATCH 731/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../Model/Product/Type/Configurable.php | 9 ++- .../Model/Product/Type/ConfigurableTest.php | 10 ++- ...ckout_cart_configure_type_configurable.xml | 4 +- .../web/js/configurable-customer-data.js | 36 ++-------- ...ckout_cart_configure_type_configurable.xml | 12 ++++ .../web/js/configurable-customer-data.js | 71 +++++++++++++++++++ 6 files changed, 107 insertions(+), 35 deletions(-) create mode 100644 app/code/Magento/Swatches/view/frontend/layout/checkout_cart_configure_type_configurable.xml create mode 100644 app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 8c1bf07a172..0b8a4aee9fe 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -898,10 +898,15 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType $value = $value->getSource()->getOptionText($attributeValue); } else { $value = ''; + $attributeValue = ''; } - $attributes[] = ['label' => $label, 'value' => $value, - 'option_id' => $attributeId, 'option_value' => $attributeValue]; + $attributes[] = [ + 'label' => $label, + 'value' => $value, + 'option_id' => $attributeId, + 'option_value' => $attributeValue + ]; } } } 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 4a49cb0b5e7..85efe886bbf 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 @@ -660,8 +660,14 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $this->assertEquals( $this->_model->getSelectedAttributesInfo($productMock), - [['label' => 'attr_store_label', 'value' => '', - 'option_id' => '1', 'option_value' => '']] + [ + [ + 'label' => 'attr_store_label', + 'value' => '', + 'option_id' => 1, + 'option_value' => [] + ] + ] ); } diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml b/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml index e34b4a99494..41655260017 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml +++ b/app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml @@ -6,9 +6,9 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> - <update handle="catalog_product_view_type_configurable"/> - <body/> <head> <link src="Magento_ConfigurableProduct::js/configurable-customer-data.js"/> </head> + <update handle="catalog_product_view_type_configurable"/> + <body/> </page> diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js index 9685af513ed..872e00918b8 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js @@ -6,29 +6,23 @@ require([ var selectors = { configurableWidget: 'mageConfigurable', - swatchWidget: 'mageSwatchRenderer', formSelector: '#product_addtocart_form', - swatchSelector: '.swatch-opt', productIdSelector: '#product_addtocart_form [name="product"]' }, configurableWidget, - swatchWidget, productOptions, tempProductOptions, cartData = customerData.get('cart'), productId = $(selectors.productIdSelector).val(), updateConfigurableOptions, - updateSwatchOptions, setProductOptions; - - /** * Sets all configurable attribute's selected values */ updateConfigurableOptions = function () { configurableWidget = $(selectors.formSelector).data(selectors.configurableWidget); - + if (!configurableWidget) { return; } @@ -36,18 +30,6 @@ require([ configurableWidget._configureForValues(); }; - /** - * Sets all configurable swatch attribute's selected values - */ - updateSwatchOptions = function () { - swatchWidget = $(selectors.swatchSelector).data(selectors.swatchWidget); - - if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) { - return; - } - swatchWidget._EmulateSelectedByAttributeId(productOptions); - }; - /** * set productOptions according to cart data from customer-data * @@ -56,7 +38,7 @@ require([ */ setProductOptions = function (data) { if (!(data && data.items && data.items.length && productId)) { - return; + return false; } tempProductOptions = data.items.find(function (item) { return item['product_id'] === productId; @@ -66,28 +48,24 @@ require([ obj[val['option_id']] = val['option_value']; return obj; - }, {}); + }, {}); - if (JSON.stringify(productOptions || {}) === JSON.stringify(tempProductOptions || {}) ) { + if (JSON.stringify(productOptions || {}) === JSON.stringify(tempProductOptions || {})) { return false; } productOptions = tempProductOptions; + return true; }; cartData.subscribe(function (updateCartData) { if (setProductOptions(updateCartData)) { updateConfigurableOptions(); - updateSwatchOptions(); } }); $(selectors.formSelector).on('configurable.initialized', function () { - setProductOptions(cartData()); - updateConfigurableOptions(); - }); - $(selectors.formSelector).on('swatch.initialized', function () { - setProductOptions(cartData()); - updateSwatchOptions(); + setProductOptions(cartData()); + updateConfigurableOptions(); }); }); diff --git a/app/code/Magento/Swatches/view/frontend/layout/checkout_cart_configure_type_configurable.xml b/app/code/Magento/Swatches/view/frontend/layout/checkout_cart_configure_type_configurable.xml new file mode 100644 index 00000000000..a48b093d7ab --- /dev/null +++ b/app/code/Magento/Swatches/view/frontend/layout/checkout_cart_configure_type_configurable.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <head> + <link src="Magento_Swatches::js/configurable-customer-data.js"/> + </head> +</page> diff --git a/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js new file mode 100644 index 00000000000..71426893a01 --- /dev/null +++ b/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js @@ -0,0 +1,71 @@ +require([ + 'jquery', + 'Magento_Customer/js/customer-data' +], function ($, customerData) { + 'use strict'; + + var selectors = { + swatchWidget: 'mageSwatchRenderer', + formSelector: '#product_addtocart_form', + swatchSelector: '.swatch-opt', + productIdSelector: '#product_addtocart_form [name="product"]' + }, + swatchWidget, + productOptions, + tempProductOptions, + cartData = customerData.get('cart'), + productId = $(selectors.productIdSelector).val(), + updateSwatchOptions, + setProductOptions; + + /** + * Sets all configurable swatch attribute's selected values + */ + updateSwatchOptions = function () { + swatchWidget = $(selectors.swatchSelector).data(selectors.swatchWidget); + + if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) { + return; + } + swatchWidget._EmulateSelectedByAttributeId(productOptions); + }; + + /** + * set productOptions according to cart data from customer-data + * + * @param {Object} data - cart data from customer-data + * @returns {Boolean} - whether the new options differ from previous + */ + setProductOptions = function (data) { + if (!(data && data.items && data.items.length && productId)) { + return false; + } + tempProductOptions = data.items.find(function (item) { + return item['product_id'] === productId; + }); + tempProductOptions = tempProductOptions && tempProductOptions.options && + tempProductOptions.options.reduce(function (obj, val) { + obj[val['option_id']] = val['option_value']; + + return obj; + }, {}); + + if (JSON.stringify(productOptions || {}) === JSON.stringify(tempProductOptions || {})) { + return false; + } + + productOptions = tempProductOptions; + + return true; + }; + + cartData.subscribe(function (updateCartData) { + if (setProductOptions(updateCartData)) { + updateSwatchOptions(); + } + }); + $(selectors.formSelector).on('swatch.initialized', function () { + setProductOptions(cartData()); + updateSwatchOptions(); + }); +}); -- GitLab From a2143f0281cb13b05ab1d8d3a31c246cf327631b Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 30 Aug 2016 16:05:31 +0300 Subject: [PATCH 732/838] MAGETWO-57140: CLONE - [GitHub] Wrong initialization sequence in mage.priceBox widget (price-box.js) #6117 FOR 2.2 - code style fix --- .../Catalog/view/base/web/js/price-box.js | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index 8f18871de82..e615e8fdd09 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -2,6 +2,7 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + define([ 'jquery', 'Magento_Catalog/js/price-utils', @@ -29,6 +30,7 @@ define([ */ _init: function initPriceBox() { var box = this.element; + box.trigger('updatePrice'); this.cache.displayPrices = utils.deepClone(this.options.prices); }, @@ -70,7 +72,8 @@ define([ updatePrice: function updatePrice(newPrices) { var prices = this.cache.displayPrices, additionalPrice = {}, - pricesCode = []; + pricesCode = [], + priceValue, origin, final; this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; @@ -89,19 +92,19 @@ define([ pricesCode = _.keys(additional); } _.each(pricesCode, function (priceCode) { - var priceValue = additional[priceCode] || {}; + priceValue = additional[priceCode] || {}; priceValue.amount = +priceValue.amount || 0; priceValue.adjustments = priceValue.adjustments || {}; additionalPrice[priceCode] = additionalPrice[priceCode] || { - 'amount': 0, - 'adjustments': {} - }; - additionalPrice[priceCode].amount = 0 + (additionalPrice[priceCode].amount || 0) - + priceValue.amount; + 'amount': 0, + 'adjustments': {} + }; + additionalPrice[priceCode].amount = 0 + (additionalPrice[priceCode].amount || 0) + + priceValue.amount; _.each(priceValue.adjustments, function (adValue, adCode) { - additionalPrice[priceCode].adjustments[adCode] = 0 - + (additionalPrice[priceCode].adjustments[adCode] || 0) + adValue; + additionalPrice[priceCode].adjustments[adCode] = 0 + + (additionalPrice[priceCode].adjustments[adCode] || 0) + adValue; }); }); }); @@ -110,8 +113,8 @@ define([ this.cache.displayPrices = utils.deepClone(this.options.prices); } else { _.each(additionalPrice, function (option, priceCode) { - var origin = this.options.prices[priceCode] || {}, - final = prices[priceCode] || {}; + origin = this.options.prices[priceCode] || {}; + final = prices[priceCode] || {}; option.amount = option.amount || 0; origin.amount = origin.amount || 0; origin.adjustments = origin.adjustments || {}; @@ -127,6 +130,7 @@ define([ this.element.trigger('reloadPrice'); }, + /*eslint-disable no-extra-parens*/ /** * Render price unit block. */ @@ -135,16 +139,19 @@ define([ priceTemplate = mageTemplate(this.options.priceTemplate); _.each(this.cache.displayPrices, function (price, priceCode) { - price.final = _.reduce(price.adjustments, function(memo, amount) { + price.final = _.reduce(price.adjustments, function (memo, amount) { return memo + amount; }, price.amount); price.formatted = utils.formatPrice(price.final, priceFormat); - $('[data-price-type="' + priceCode + '"]', this.element).html(priceTemplate({data: price})); + $('[data-price-type="' + priceCode + '"]', this.element).html(priceTemplate({ + data: price + })); }, this); }, + /*eslint-enable no-extra-parens*/ /** * Overwrites initial (default) prices object. * @param {Object} prices @@ -177,6 +184,7 @@ define([ var box = this.element, priceHolders = $('[data-price-type]', box), prices = this.options.prices; + this.options.productId = box.data('productId'); if (_.isEmpty(prices)) { -- GitLab From 34298595c3b1b96cc59ea62d05463b4205731a5e Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 30 Aug 2016 16:12:40 +0300 Subject: [PATCH 733/838] MAGETWO-57140: CLONE - [GitHub] Wrong initialization sequence in mage.priceBox widget (price-box.js) #6117 FOR 2.2 --- .../testsuite/Magento/Test/Js/_files/blacklist/magento.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt index 25d39417fa7..77cf93864b0 100644 --- a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt +++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt @@ -34,7 +34,6 @@ app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js app/code/Magento/Catalog/view/adminhtml/web/js/custom-options.js app/code/Magento/Catalog/view/adminhtml/web/js/new-category-dialog.js app/code/Magento/Catalog/view/adminhtml/web/js/product-gallery.js -app/code/Magento/Catalog/view/base/web/js/price-box.js app/code/Magento/Catalog/view/base/web/js/price-option-date.js app/code/Magento/Catalog/view/base/web/js/price-option-file.js app/code/Magento/Catalog/view/base/web/js/price-options.js -- GitLab From 65f6300b37d1fa9d977569112a94d148cd8a2585 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 30 Aug 2016 16:39:33 +0300 Subject: [PATCH 734/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../web/js/configurable-customer-data.js | 12 +++++------ .../web/js/configurable-customer-data.js | 12 +++++------ .../view/frontend/web/js/swatch-renderer.js | 20 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js index 872e00918b8..b98f7520549 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js @@ -11,7 +11,7 @@ require([ }, configurableWidget, productOptions, - tempProductOptions, + changedProductOptions, cartData = customerData.get('cart'), productId = $(selectors.productIdSelector).val(), updateConfigurableOptions, @@ -40,21 +40,21 @@ require([ if (!(data && data.items && data.items.length && productId)) { return false; } - tempProductOptions = data.items.find(function (item) { + changedProductOptions = data.items.find(function (item) { return item['product_id'] === productId; }); - tempProductOptions = tempProductOptions && tempProductOptions.options && - tempProductOptions.options.reduce(function (obj, val) { + changedProductOptions = changedProductOptions && changedProductOptions.options && + changedProductOptions.options.reduce(function (obj, val) { obj[val['option_id']] = val['option_value']; return obj; }, {}); - if (JSON.stringify(productOptions || {}) === JSON.stringify(tempProductOptions || {})) { + if (JSON.stringify(productOptions || {}) === JSON.stringify(changedProductOptions || {})) { return false; } - productOptions = tempProductOptions; + productOptions = changedProductOptions; return true; }; diff --git a/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js index 71426893a01..cea3d6312d3 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js @@ -12,7 +12,7 @@ require([ }, swatchWidget, productOptions, - tempProductOptions, + changedProductOptions, cartData = customerData.get('cart'), productId = $(selectors.productIdSelector).val(), updateSwatchOptions, @@ -40,21 +40,21 @@ require([ if (!(data && data.items && data.items.length && productId)) { return false; } - tempProductOptions = data.items.find(function (item) { + changedProductOptions = data.items.find(function (item) { return item['product_id'] === productId; }); - tempProductOptions = tempProductOptions && tempProductOptions.options && - tempProductOptions.options.reduce(function (obj, val) { + changedProductOptions = changedProductOptions && changedProductOptions.options && + changedProductOptions.options.reduce(function (obj, val) { obj[val['option_id']] = val['option_value']; return obj; }, {}); - if (JSON.stringify(productOptions || {}) === JSON.stringify(tempProductOptions || {})) { + if (JSON.stringify(productOptions || {}) === JSON.stringify(changedProductOptions || {})) { return false; } - productOptions = tempProductOptions; + productOptions = changedProductOptions; return true; }; diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index e748f0edb6d..58e248c3962 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -962,17 +962,17 @@ define([ var elem = this.element.find('.' + this.options.classes.attributeClass + '[attribute-id="' + attributeId + '"] [option-id="' + optionId + '"]'), parentInput = elem.parent(); - - if (elem.hasClass('selected')) { - return; - } - if (parentInput.hasClass(this.options.classes.selectClass)) { - parentInput.val(optionId); - parentInput.trigger('change'); - } else { - elem.trigger('click'); - } + if (elem.hasClass('selected')) { + return; + } + + if (parentInput.hasClass(this.options.classes.selectClass)) { + parentInput.val(optionId); + parentInput.trigger('change'); + } else { + elem.trigger('click'); + } }, this)); }, -- GitLab From 4e52ac86e62b4fea3a34842833548e41cc3b847d Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 30 Aug 2016 16:40:43 +0300 Subject: [PATCH 735/838] MAGETWO-57140: CLONE - [GitHub] Wrong initialization sequence in mage.priceBox widget (price-box.js) #6117 FOR 2.2 --- app/code/Magento/Catalog/view/base/web/js/price-box.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index e615e8fdd09..8d1bec72a23 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -73,7 +73,7 @@ define([ var prices = this.cache.displayPrices, additionalPrice = {}, pricesCode = [], - priceValue, origin, final; + priceValue, origin, finalPrice; this.cache.additionalPriceObject = this.cache.additionalPriceObject || {}; @@ -114,15 +114,15 @@ define([ } else { _.each(additionalPrice, function (option, priceCode) { origin = this.options.prices[priceCode] || {}; - final = prices[priceCode] || {}; + finalPrice = prices[priceCode] || {}; option.amount = option.amount || 0; origin.amount = origin.amount || 0; origin.adjustments = origin.adjustments || {}; - final.adjustments = final.adjustments || {}; + finalPrice.adjustments = finalPrice.adjustments || {}; - final.amount = 0 + origin.amount + option.amount; + finalPrice.amount = 0 + origin.amount + option.amount; _.each(option.adjustments, function (pa, paCode) { - final.adjustments[paCode] = 0 + (origin.adjustments[paCode] || 0) + pa; + finalPrice.adjustments[paCode] = 0 + (origin.adjustments[paCode] || 0) + pa; }); }, this); } -- GitLab From d78f3739800cb5d5c7f31cb76683fab5af85f9f6 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 30 Aug 2016 17:03:13 +0300 Subject: [PATCH 736/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../Test/Unit/Model/Product/Type/ConfigurableTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 85efe886bbf..d2fd41cecda 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 @@ -665,7 +665,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase 'label' => 'attr_store_label', 'value' => '', 'option_id' => 1, - 'option_value' => [] + 'option_value' => '' ] ] ); -- GitLab From 59c2c9e8dd89e6452a5a861595bc88b8ebd9c5f3 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 09:03:37 -0500 Subject: [PATCH 737/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 167 +++++++++++++++++- .../Framework/Test/Unit/EscaperTest.php | 88 +++++++-- 2 files changed, 236 insertions(+), 19 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fe88e2b0792..7d99ee2318c 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -16,25 +16,81 @@ class Escaper private $escaper; /** - * Escape HTML entities + * @var \Psr\Log\LoggerInterface + */ + private $logger; + + /** + * @var string[] + */ + private $notAllowedTags = ['script', 'img']; + + /** + * @var string[] + */ + private $allowedAttributes = ['id', 'class', 'href', 'target', 'title']; + + /** + * @var string[] + */ + private $escapeAsUrlAttributes = ['href']; + + /** + * Escape string for HTML context, allowedTags will not be escaped * * @param string|array $data * @param array $allowedTags * @return string|array */ - public function escapeHtml($data, $allowedTags = null) + public function escapeHtml($data, $allowedTags = []) { if (is_array($data)) { $result = []; foreach ($data as $item) { - $result[] = $this->escapeHtml($item); + $result[] = $this->escapeHtml($item, $allowedTags); } } elseif (strlen($data)) { if (is_array($allowedTags) && !empty($allowedTags)) { - $allowed = implode('|', $allowedTags); - $result = preg_replace('/<([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)>/si', '##$1$2$3##', $data); - $result = htmlspecialchars($result, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); - $result = preg_replace('/##([\/\s\r\n]*)(' . $allowed . ')([\/\s\r\n]*)##/si', '<$1$2$3>', $result); + $notAllowedTags = array_intersect( + array_map('strtolower', $allowedTags), + $this->notAllowedTags + ); + if (!empty($notAllowedTags)) { + $this->getLogger()->critical( + 'The following tag(s) are not allowed: ' . implode(', ', $notAllowedTags) + ); + return ''; + } + $wrapperElementId = uniqid(); + $domDocument = new \DOMDocument('1.0', 'UTF-8'); + set_error_handler( + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + function ($errorNumber, $errorString, $errorFile, $errorLine) { + throw new \Exception($errorString, $errorNumber); + } + ); + $string = mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8'); + try { + $domDocument->loadHTML( + '<html><body id="' . $wrapperElementId . '">' . $string . '</body></html>' + ); + } catch (\Exception $e) { + restore_error_handler(); + $this->getLogger()->critical($e); + return ''; + } + restore_error_handler(); + + $this->removeNotAllowedTags($domDocument, $allowedTags); + $this->removeNotAllowedAttributes($domDocument); + $this->escapeText($domDocument); + $this->escapeAttributeValues($domDocument); + + $result = mb_convert_encoding($domDocument->saveHTML(), 'UTF-8', 'HTML-ENTITIES'); + preg_match('/<body id="' . $wrapperElementId . '">(.+)<\/body><\/html>$/si', $result, $matches); + return $matches[1]; } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } @@ -44,6 +100,88 @@ class Escaper return $result; } + /** + * Remove not allowed tags + * + * @param \DOMDocument $domDocument + * @param string[] $allowedTags + * @return void + */ + private function removeNotAllowedTags(\DOMDocument $domDocument, array $allowedTags) + { + $xpath = new \DOMXPath($domDocument); + $nodes = $xpath->query('//node()[name() != \'' + . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) . '\']'); + foreach ($nodes as $node) { + if ($node->nodeName != '#text' && $node->nodeName != '#comment') { + $node->parentNode->replaceChild($domDocument->createTextNode($node->textContent), $node); + } + } + } + + /** + * Remove not allowed attributes + * + * @param \DOMDocument $domDocument + * @return void + */ + private function removeNotAllowedAttributes(\DOMDocument $domDocument) + { + $xpath = new \DOMXPath($domDocument); + $nodes = $xpath->query( + '//@*[name() != \'' . implode('\' and name() != \'', $this->allowedAttributes) . '\']' + ); + foreach ($nodes as $node) { + $node->parentNode->removeAttribute($node->nodeName); + } + } + + /** + * Escape text + * + * @param \DOMDocument $domDocument + * @return void + */ + private function escapeText(\DOMDocument $domDocument) + { + $xpath = new \DOMXPath($domDocument); + $nodes = $xpath->query('//text()'); + foreach ($nodes as $node) { + $node->textContent = $this->escapeHtml($node->textContent); + } + } + + /** + * Escape attribute values + * + * @param \DOMDocument $domDocument + * @return void + */ + private function escapeAttributeValues(\DOMDocument $domDocument) + { + $xpath = new \DOMXPath($domDocument); + $nodes = $xpath->query('//@*'); + foreach ($nodes as $node) { + $value = $this->escapeAttributeValue( + $node->nodeName, + $node->parentNode->getAttribute($node->nodeName) + ); + $node->parentNode->setAttribute($node->nodeName, $value); + } + } + + /** + * Escape attribute value using escapeHtml or escapeUrl + * + * @param string $name + * @param string $value + * @return string + */ + private function escapeAttributeValue($name, $value) + { + return in_array($name, $this->escapeAsUrlAttributes) ? $this->escapeUrl($value) : $this->escapeHtml($value); + } + /** * Escape a string for the HTML attribute context * @@ -172,4 +310,19 @@ class Escaper } return $this->escaper; } + + /** + * Get logger + * + * @return \Psr\Log\LoggerInterface + * @deprecated + */ + private function getLogger() + { + if ($this->logger == null) { + $this->logger = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Psr\Log\LoggerInterface::class); + } + return $this->logger; + } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 7348537c326..27c8a9f3bd8 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -23,20 +23,42 @@ class EscaperTest extends \PHPUnit_Framework_TestCase */ private $zendEscaper; + /** + * @var \Psr\Log\LoggerInterface + */ + private $loggerMock; + protected function setUp() { $this->_escaper = new Escaper(); $this->zendEscaper = new \Magento\Framework\ZendEscaper(); + $this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class); $objectManagerHelper = new ObjectManager($this); $objectManagerHelper->setBackwardCompatibleProperty($this->_escaper, 'escaper', $this->zendEscaper); + $objectManagerHelper->setBackwardCompatibleProperty($this->_escaper, 'logger', $this->loggerMock); } /** * @covers \Magento\Framework\Escaper::escapeHtml * @dataProvider escapeHtmlDataProvider */ - public function testEscapeHtml($data, $expected, $allowedTags = null) + public function testEscapeHtml($data, $expected, $allowedTags = []) + { + $actual = $this->_escaper->escapeHtml($data, $allowedTags); + $this->assertEquals($expected, $actual); + } + + /** + * @covers \Magento\Framework\Escaper::escapeHtml + */ + public function testEscapeHtmlWithInvalidData() { + $data = '<span><script>some text in tags</script></span>'; + $expected = ''; + $allowedTags = ['script', 'span']; + $this->loggerMock->expects($this->once()) + ->method('critical') + ->with('The following tag(s) can not be used in the translation: script'); $actual = $this->_escaper->escapeHtml($data, $allowedTags); $this->assertEquals($expected, $actual); } @@ -47,22 +69,64 @@ class EscaperTest extends \PHPUnit_Framework_TestCase public function escapeHtmlDataProvider() { return [ - 'array data' => [ + 'array -> [text with no tags, text with no allowed tags]' => [ 'data' => ['one', '<two>three</two>'], 'expected' => ['one', '<two>three</two>'], - null, ], - 'string data conversion' => [ - 'data' => '<two>three</two>', - 'expected' => '<two>three</two>', - null, + 'text with special characters' => [ + 'data' => '&<>"\'&<>"'	', + 'expected' => '&<>"'&<>"'	' + ], + 'text with multiple allowed tags, includes self closing tag' => [ + 'data' => '<span>some text in tags<br /></span>', + 'expected' => '<span>some text in tags<br></span>', + 'allowedTags' => ['span', 'br'], ], - 'string data no conversion' => ['data' => 'one', 'expected' => 'one'], - 'string data with allowed tags' => [ - 'data' => '<span><b>some text in tags</b></span>', - 'expected' => '<span><b>some text in tags</b></span>', + 'text with multiple allowed tags and allowed attribute in double quotes' => [ + 'data' => 'Only <span id="sku_max_allowed"><b>2</b></span> in stock', + 'expected' => 'Only <span id="sku_max_allowed"><b>2</b></span> in stock', 'allowedTags' => ['span', 'b'], - ] + ], + 'text with multiple allowed tags and allowed attribute in single quotes' => [ + 'data' => 'Only <span id=\'sku_max_allowed\'><b>2</b></span> in stock', + 'expected' => 'Only <span id="sku_max_allowed"><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + 'text with multiple allowed tags with allowed attribute' => [ + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'allowedTags' => ['a'], + ], + 'text with not allowed attribute in single quotes' => [ + 'data' => 'Only <span type=\'1\'><b>2</b></span> in stock', + 'expected' => 'Only <span><b>2</b></span> in stock', + 'allowedTags' => ['span', 'b'], + ], + 'text with allowed and not allowed tags' => [ + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> or <a href="%2">create an account</a>', + 'allowedTags' => ['a'], + ], + 'text with allowed and not allowed tags, with allowed and not allowed attributes' => [ + 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a type="some-type" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', + 'expected' => 'Some test <span>text in span tag</span> text in strong tag <a href="http://domain.com/">Click here</a>alert(1)', + 'allowedTags' => ['a', 'span'], + ], + 'text with html comment' => [ + 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'allowedTags' => ['span', 'b'], + ], + 'text with non ascii characters' => [ + 'data' => ['абвгд', 'مثال'], + 'expected' => ['абвгд', 'مثال'], + 'allowedTags' => [], + ], + 'html and body tags' => [ + 'data' => '<html><body><span>String</span></body></html>', + 'expected' => '', + 'allowedTags' => ['span'], + ], ]; } -- GitLab From 70adf337b1e10d89eab7f1af9b7bb45208c86f96 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 09:10:50 -0500 Subject: [PATCH 738/838] MAGETWO-57836: Make \Magento\Framework\Escaper::escapeJs() generate valid Json string --- lib/internal/Magento/Framework/Escaper.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fe88e2b0792..e51f4b5261b 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -89,7 +89,17 @@ class Escaper */ public function escapeJs($string) { - return $this->getEscaper()->escapeJs($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + return preg_replace_callback( + '/[^a-z0-9,\._]/iSu', + function ($matches) { + return sprintf('\\u%04s', strtoupper(bin2hex($matches[0]))); + }, + $string + ); } /** -- GitLab From 2a539359e3b64b47b81ff70c8b1acd4d703d0995 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 09:16:19 -0500 Subject: [PATCH 739/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Eliminating @escapeNotVerified annotation --- .../view/frontend/templates/javascript.phtml | 5 +++-- .../view/frontend/templates/js/components.phtml | 1 - .../view/frontend/templates/switch/flags.phtml | 5 ++--- .../view/frontend/templates/switch/languages.phtml | 13 +++++++------ .../view/frontend/templates/switch/stores.phtml | 3 +-- .../adminhtml/templates/translate_inline.phtml | 6 ++---- .../view/base/templates/translate.phtml | 14 ++++++++------ .../view/frontend/templates/translate_inline.phtml | 12 +++++------- 8 files changed, 28 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml b/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml index 879556c41d5..830924c2691 100644 --- a/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml +++ b/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml @@ -3,12 +3,13 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** @var \Magento\PageCache\Block\Javascript $block */ ?> -<?php /** @var \Magento\PageCache\Block\Javascript $block */ ?> <script type="text/x-magento-init"> { "body": { - "pageCache": <?php /* @escapeNotVerified */ echo $block->getScriptOptions(); ?> + "pageCache": <?php /* @noEscape */ echo $block->getScriptOptions(); ?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml index e490a6aa049..7e508809b96 100644 --- a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml +++ b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml @@ -5,6 +5,5 @@ */ // @codingStandardsIgnoreFile - ?> <?php echo $block->getChildHtml() ?> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml index 53d4428172a..9c28bd1c104 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml @@ -5,15 +5,14 @@ */ // @codingStandardsIgnoreFile - ?> <?php if (count($block->getStores())>1): ?> <div class="form-language"> <label for="select-language"><?php echo $block->escapeHtml(__('Your Language:')) ?></label> - <select id="select-language" title="<?php echo $block->escapeHtml(__('Your Language')) ?>" onchange="window.location.href=this.value" class="flags"> + <select id="select-language" title="<?php echo $block->escapeHtmlAttr(__('Your Language')) ?>" onchange="window.location.href=this.value" class="flags"> <?php foreach ($block->getStores() as $_lang): ?> <?php $_selected = ($_lang->getId() == $block->getCurrentStoreId()) ? ' selected="selected"' : '' ?> - <option value="<?php /* @escapeNotVerified */ echo $_lang->getCurrentUrl() ?>" style="background-image:url('<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif') ?>');"<?php /* @escapeNotVerified */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> + <option value="<?php echo $block->escapeUrl($_lang->getCurrentUrl()) ?>" style="background-image:url('<?php echo $block->escapeUrl($block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif')) ?>');"<?php /* @noEscape */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> <?php endforeach; ?> </select> </div> 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 5f32021de34..48432e772b3 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -15,18 +15,18 @@ <?php if (count($block->getStores())>1): ?> <?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> -<div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php /* @escapeNotVerified */ echo $id?>"> +<div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php /* @noEscape */ echo $id ?>"> <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Language')) ?></span></strong> <div class="actions dropdown options switcher-options"> - <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php /* @escapeNotVerified */ echo $id?>"> + <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php /* @noEscape */ echo $id ?>"> <strong class="view-<?php echo $block->escapeHtml($block->getCurrentStoreCode()) ?>"> <span><?php echo $block->escapeHtml($block->getStoreName()) ?></span> </strong> </div> <ul class="dropdown switcher-dropdown" data-mage-init='{"dropdownDialog":{ - "appendTo":"#switcher-language<?php /* @escapeNotVerified */ echo $id ?> > .options", - "triggerTarget":"#switcher-language-trigger<?php /* @escapeNotVerified */ echo $id ?>", + "appendTo":"#switcher-language<?php /* @noEscape */ echo $id ?> > .options", + "triggerTarget":"#switcher-language-trigger<?php /* @noEscape */ echo $id ?>", "closeOnMouseLeave": false, "triggerClass":"active", "parentClass":"active", @@ -34,8 +34,9 @@ <?php foreach ($block->getStores() as $_lang): ?> <?php if ($_lang->getId() != $block->getCurrentStoreId()): ?> <li class="view-<?php echo $block->escapeHtml($_lang->getCode()); ?> switcher-option"> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getTargetStorePostData($_lang); ?>'> - <?php echo $block->escapeHtml($_lang->getName()) ?></a> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getTargetStorePostData($_lang); ?>'> + <?php echo $block->escapeHtml($_lang->getName()) ?> + </a> </li> <?php endif; ?> <?php endforeach; ?> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml index d19797285b7..3b9fceb787f 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml @@ -37,8 +37,7 @@ <?php foreach ($block->getGroups() as $_group): ?> <?php if (!($_group->getId() == $block->getCurrentGroupId())): ?> <li class="switcher-option"> - <a href="#" - data-post='<?php /* @escapeNotVerified */ echo $block->getTargetStorePostData($_group->getDefaultStore()); ?>'> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getTargetStorePostData($_group->getDefaultStore()); ?>'> <?php echo $block->escapeHtml($_group->getName()) ?> </a> </li> diff --git a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml index 08b64dc3a69..689e93455a7 100644 --- a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml @@ -5,9 +5,7 @@ */ // @codingStandardsIgnoreFile - ?> - <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> @@ -53,7 +51,7 @@ <% } %> </script> -<div data-role="translate-dialog" data-mage-init='{"translateInline":{"ajaxUrl":"<?php echo $block->escapeUrl($block->getAjaxUrl()) ?>"},"loader":{}}'></div> +<div data-role="translate-dialog" data-mage-init='{"translateInline":{"ajaxUrl":"<?php echo $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>"},"loader":{}}'></div> <script> require([ "jquery", @@ -62,7 +60,7 @@ require([ ], function($){ $('body').editTrigger( { - img: '<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Theme::fam_book_open.png')) ?>', + img: '<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::fam_book_open.png'))) ?>', alwaysShown: true, singleElement: false } diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index 1bbf6979bf3..3471a1bbafd 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -3,9 +3,11 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + // @codingStandardsIgnoreFile + + /** @var \Magento\Translation\Block\Js $block */ ?> -<?php /** @var $block \Magento\Translation\Block\Js */ ?> <?php if ($block->dictionaryEnabled()): ?> <script> require.config({ @@ -24,10 +26,11 @@ $.initNamespaceStorage('mage-translation-file-version'); versionObj = $.localStorage.get('mage-translation-file-version'); - if (versionObj.version !== '<?php /* @escapeNotVerified */ - echo sha1($block->getTranslationFileTimestamp() . $block->getTranslationFilePath()) ?>') { + <?php $version = sha1($block->getTranslationFileTimestamp() . $block->getTranslationFilePath()); ?> + + if (versionObj.version !== '<?php /* @noEscape */ echo $version ?>') { dependencies.push( - 'text!<?php /* @escapeNotVerified */ echo Magento\Translation\Model\Js\Config::DICTIONARY_FILE_NAME?>' + 'text!<?php /* @noEscape */ echo Magento\Translation\Model\Js\Config::DICTIONARY_FILE_NAME ?>' ); } @@ -41,8 +44,7 @@ $.localStorage.set( 'mage-translation-file-version', { - version: '<?php /* @escapeNotVerified */ - echo sha1($block->getTranslationFileTimestamp() . $block->getTranslationFilePath()) ?>' + version: '<?php /* @noEscape */ echo $version ?>' } ); } else { diff --git a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml index 81e6ad79602..797222f23a3 100644 --- a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml @@ -5,12 +5,10 @@ */ // @codingStandardsIgnoreFile - ?> - -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('prototype/windows/themes/default.css') ?>"/> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Theme::prototype/magento.css') ?>"/> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('mage/translate-inline.css') ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css'))) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::prototype/magento.css'))) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css'))) ?>"/> <script id="translate-inline-icon" type="text/x-magento-template"> <img src="<%- data.img %>" height="16" width="16" class="translate-edit-icon"> @@ -56,12 +54,12 @@ </script> <div data-role="translate-dialog" - data-mage-init='{"translateInline":{"ajaxUrl":"<?php /* @escapeNotVerified */ echo $block->getAjaxUrl() ?>"},"loader":{}}'></div> + data-mage-init='{"translateInline":{"ajaxUrl":"<?php echo $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>"},"loader":{}}'></div> <script type="text/x-magento-init"> { "body": { "editTrigger": { - "img": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Theme::fam_book_open.png') ?>", + "img": "<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::fam_book_open.png'))) ?>", "alwaysShown":true, "singleElement":false }, -- GitLab From b5386c398ba641f8dbf2ba470ab6404a7a178061 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 09:24:35 -0500 Subject: [PATCH 740/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 27c8a9f3bd8..2b79a7b878d 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -58,7 +58,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase $allowedTags = ['script', 'span']; $this->loggerMock->expects($this->once()) ->method('critical') - ->with('The following tag(s) can not be used in the translation: script'); + ->with('The following tag(s) are not allowed: script'); $actual = $this->_escaper->escapeHtml($data, $allowedTags); $this->assertEquals($expected, $actual); } -- GitLab From c8890916adfa7f3de683fba72a5a12ac3b9389ca Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 09:26:39 -0500 Subject: [PATCH 741/838] MAGETWO-57233: Eliminate @escapeNotVerified in Captcha, Contact, Cookie, Persistent, Rss, Sendfriend Module --- .../Magento/Cookie/view/frontend/templates/html/notices.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml index 8488daeb86e..7b6e178447f 100644 --- a/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml +++ b/app/code/Magento/Cookie/view/frontend/templates/html/notices.phtml @@ -35,7 +35,7 @@ "cookieName": "<?php /* @noEscape */ echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>", "cookieValue": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getAcceptedSaveCookiesWebsiteIds() ?>, "cookieLifetime": <?php /* @noEscape */ echo $this->helper(\Magento\Cookie\Helper\Cookie::class)->getCookieRestrictionLifetime()?>, - "noCookiesUrl": "<?php echo $block->escapeUrl($block->getUrl('cookie/index/noCookies')) ?>" + "noCookiesUrl": "<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('cookie/index/noCookies'))) ?>" } } } -- GitLab From 691604af2effe1c1695139e3fae4e08cdeea5a5e Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 09:34:47 -0500 Subject: [PATCH 742/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../frontend/templates/account/authentication-popup.phtml | 2 +- .../Customer/view/frontend/templates/address/book.phtml | 4 ++-- .../Customer/view/frontend/templates/form/edit.phtml | 6 +++--- .../Customer/view/frontend/templates/form/register.phtml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml index 2b62b1f6fb7..f34cc41344e 100644 --- a/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/account/authentication-popup.phtml @@ -19,7 +19,7 @@ "Magento_Ui/js/core/app": <?php /* @noEscape */ echo $block->getJsLayout();?> }, "*": { - "Magento_Ui/js/block-loader": "<?php echo $block->escapeUrl($block->getViewFileUrl('images/loader-1.gif')); ?>" + "Magento_Ui/js/block-loader": "<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('images/loader-1.gif'))); ?>" } } </script> diff --git a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml index fe45a6132b0..37ab2584c84 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/book.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/book.phtml @@ -99,9 +99,9 @@ ".page-main": { "address": { "deleteAddress": "li.item a[role='delete-address']", - "deleteUrlPrefix": "<?php echo $block->escapeUrl($block->getDeleteUrl()) ?>id/", + "deleteUrlPrefix": "<?php echo $block->escapeJs($block->escapeUrl($block->getDeleteUrl())) ?>id/", "addAddress": "button[role='add-address']", - "addAddressLocation": "<?php echo $block->escapeUrl($block->getAddAddressUrl()) ?>" + "addAddressLocation": "<?php echo $block->escapeJs($block->escapeUrl($block->getAddAddressUrl())) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml index 6c1d349a754..716378f4fc1 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/edit.phtml @@ -122,9 +122,9 @@ { "[data-role=change-email], [data-role=change-password]": { "changeEmailPassword": { - "titleChangeEmail": "<?php echo $block->escapeHtml(__('Change Email')) ?>", - "titleChangePassword": "<?php echo $block->escapeHtml(__('Change Password')) ?>", - "titleChangeEmailAndPassword": "<?php echo $block->escapeHtml(__('Change Email and Password')) ?>" + "titleChangeEmail": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Email'))) ?>", + "titleChangePassword": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Password'))) ?>", + "titleChangeEmailAndPassword": "<?php echo $block->escapeJs($block->escapeHtml(__('Change Email and Password'))) ?>" } } } diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index f9fe8c69b48..fb51e056d16 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -210,7 +210,7 @@ require([ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeHtml($block->getFormData()->getRegionId()) ?>", + "defaultRegion": "<?php echo $block->escapeJs($block->escapeHtml($block->getFormData()->getRegionId())) ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getCountriesWithOptionalZip(true) ?> } } -- GitLab From d8d80d6366ac37404d778ad58d6bdc462a622c36 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 09:37:08 -0500 Subject: [PATCH 743/838] MAGETWO-57237: Eliminate @escapeNotVerified in Review Module --- app/code/Magento/Review/view/frontend/templates/review.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Review/view/frontend/templates/review.phtml b/app/code/Magento/Review/view/frontend/templates/review.phtml index a7459ca7e1b..c3f64511b15 100644 --- a/app/code/Magento/Review/view/frontend/templates/review.phtml +++ b/app/code/Magento/Review/view/frontend/templates/review.phtml @@ -13,7 +13,7 @@ { "*": { "Magento_Review/js/process-reviews": { - "productReviewUrl": "<?php echo $block->escapeUrl($block->getProductReviewUrl()); ?>" + "productReviewUrl": "<?php echo $block->escapeJs($block->escapeUrl($block->getProductReviewUrl())); ?>" } } } -- GitLab From 6cda636a40d8ac71ff4ca47cd821e182b0577174 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 09:47:13 -0500 Subject: [PATCH 744/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Fixing annotation --- .../view/adminhtml/templates/page_cache_validation.phtml | 3 +-- .../PageCache/view/frontend/templates/js/components.phtml | 2 ++ .../Store/view/frontend/templates/switch/flags.phtml | 2 ++ .../Store/view/frontend/templates/switch/languages.phtml | 7 +------ .../Store/view/frontend/templates/switch/stores.phtml | 8 +------- .../view/adminhtml/templates/translate_inline.phtml | 2 ++ .../Translation/view/base/templates/translate.phtml | 2 +- .../view/frontend/templates/translate_inline.phtml | 2 ++ 8 files changed, 12 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml b/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml index f6454d0ad9a..828a70465a2 100644 --- a/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml +++ b/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml @@ -3,9 +3,8 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -?> -<?php /** @var \Magento\PageCache\Block\System\Config\Form\Field\Export $block */ +/** @var \Magento\PageCache\Block\System\Config\Form\Field\Export $block */ ?> <script> require(['jquery'], function($){ diff --git a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml index 7e508809b96..e9fce4fe161 100644 --- a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml +++ b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml @@ -5,5 +5,7 @@ */ // @codingStandardsIgnoreFile + +/** \Magento\Framework\View\Element\Js\Components $block */ ?> <?php echo $block->getChildHtml() ?> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml index 9c28bd1c104..cbf94a8e0d7 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml @@ -5,6 +5,8 @@ */ // @codingStandardsIgnoreFile + +// @deprecated ?> <?php if (count($block->getStores())>1): ?> <div class="form-language"> 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 48432e772b3..c2d2cce1318 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -6,13 +6,8 @@ // @codingStandardsIgnoreFile +/** \Magento\Store\Block\Switcher $block */ ?> -<?php -/** - * Language switcher template - */ -?> - <?php if (count($block->getStores())>1): ?> <?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> <div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php /* @noEscape */ echo $id ?>"> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml index 3b9fceb787f..8e5bcc43670 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml @@ -6,13 +6,7 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * Store switcher template - * - * @see \Magento\Store\Block\Store\Switcher - */ +/** \Magento\Store\Block\Switcher $block */ ?> <?php if (count($block->getGroups())>1): ?> <div class="switcher store switcher-store" id="switcher-store"> diff --git a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml index 689e93455a7..959ce4f1fa5 100644 --- a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml @@ -5,6 +5,8 @@ */ // @codingStandardsIgnoreFile + +/** \Magento\Framework\View\Element\Template $block */ ?> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index 3471a1bbafd..f95376b1a32 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile - /** @var \Magento\Translation\Block\Js $block */ +/** @var \Magento\Translation\Block\Js $block */ ?> <?php if ($block->dictionaryEnabled()): ?> <script> diff --git a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml index 797222f23a3..64e7df181b2 100644 --- a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml @@ -5,6 +5,8 @@ */ // @codingStandardsIgnoreFile + +/** \Magento\Framework\View\Element\Template $block */ ?> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css'))) ?>"/> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::prototype/magento.css'))) ?>"/> -- GitLab From e825835fddaf3ed509d3f7fab47bf8b125be0065 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Tue, 30 Aug 2016 17:50:40 +0300 Subject: [PATCH 745/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../Model/Product/Type/ConfigurableTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 cb4320281a0..817effc369d 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 @@ -301,7 +301,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $product->addCustomOption('attributes', serialize([$attribute['attribute_id'] => $optionValueId])); $info = $this->model->getSelectedAttributesInfo($product); - $this->assertEquals([['label' => 'Test Configurable', 'value' => 'Option 1']], $info); + $this->assertEquals('Test Configurable', $info['label']); + $this->assertEquals('Option 1', $info['value']); } /** @@ -322,7 +323,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $attribute->getProductAttribute()->setStoreLabel('store label'); $info = $this->model->getSelectedAttributesInfo($this->product); - $this->assertEquals([['label' => 'store label', 'value' => 'Option 1']], $info); + $this->assertEquals('store label', $info['label']); + $this->assertEquals('Option 1', $info['value']); } /** @@ -369,10 +371,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $result = $this->model->getOrderOptions($product); $this->assertArrayHasKey('info_buyRequest', $result); $this->assertArrayHasKey('attributes_info', $result); - $this->assertEquals( - [['label' => 'Test Configurable', 'value' => 'Option 1']], - $result['attributes_info'] - ); + $this->assertEquals('Test Configurable', $result['attributes_info']['label']); + $this->assertEquals('Option 1', $result['attributes_info']['value']); $this->assertArrayHasKey('product_calculations', $result); $this->assertArrayHasKey('shipment_type', $result); $this->assertEquals( -- GitLab From b86c344ea8cc195e3b5d0060cad91ecdad165e0b Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 10:04:35 -0500 Subject: [PATCH 746/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Fixing annotation --- .../PageCache/view/frontend/templates/js/components.phtml | 2 +- .../Store/view/frontend/templates/switch/languages.phtml | 2 +- .../Magento/Store/view/frontend/templates/switch/stores.phtml | 2 +- .../Translation/view/adminhtml/templates/translate_inline.phtml | 2 +- .../Translation/view/frontend/templates/translate_inline.phtml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml index e9fce4fe161..b97c9edc8c0 100644 --- a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml +++ b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml @@ -6,6 +6,6 @@ // @codingStandardsIgnoreFile -/** \Magento\Framework\View\Element\Js\Components $block */ +/** @var \Magento\Framework\View\Element\Js\Components $block */ ?> <?php echo $block->getChildHtml() ?> 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 c2d2cce1318..cf499148e61 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** \Magento\Store\Block\Switcher $block */ +/** @var \Magento\Store\Block\Switcher $block */ ?> <?php if (count($block->getStores())>1): ?> <?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml index 8e5bcc43670..38c187aa273 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** \Magento\Store\Block\Switcher $block */ +/** @var \Magento\Store\Block\Switcher $block */ ?> <?php if (count($block->getGroups())>1): ?> <div class="switcher store switcher-store" id="switcher-store"> diff --git a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml index 959ce4f1fa5..4f34e9eebd9 100644 --- a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** \Magento\Framework\View\Element\Template $block */ +/** @var \Magento\Framework\View\Element\Template $block */ ?> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> diff --git a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml index 64e7df181b2..1df0995f7a2 100644 --- a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml @@ -6,7 +6,7 @@ // @codingStandardsIgnoreFile -/** \Magento\Framework\View\Element\Template $block */ +/** @var \Magento\Framework\View\Element\Template $block */ ?> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css'))) ?>"/> <link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::prototype/magento.css'))) ?>"/> -- GitLab From 147280b00c80fb2c71423b14b4ed924767e2b1c7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 10:05:49 -0500 Subject: [PATCH 747/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../view/adminhtml/templates/system/config/validatevat.phtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml index 18f843d6566..c20092554bf 100644 --- a/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml +++ b/app/code/Magento/Customer/view/adminhtml/templates/system/config/validatevat.phtml @@ -16,8 +16,8 @@ require(['prototype'], function(){ var validationMessage = $('validation_result'); params = { - country: $('<?php echo $block->escapeJs($block->escapeHtml($block->getMerchantCountryField())); ?>').value, - vat: $('<?php echo $block->escapeJs($block->escapeHtml($block->getMerchantVatNumberField())); ?>').value + country: $('<?php echo $block->escapeJs($block->getMerchantCountryField()); ?>').value, + vat: $('<?php echo $block->escapeJs($block->getMerchantVatNumberField()); ?>').value }; new Ajax.Request('<?php echo $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>', { -- GitLab From b42c3b97ba0a2ca53d2bf523818414bd09f98c35 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 10:10:23 -0500 Subject: [PATCH 748/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Eliminating @escapeNotVerified annotation --- .../Magento/Store/view/frontend/templates/switch/flags.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml index cbf94a8e0d7..cb151bded68 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml @@ -14,7 +14,7 @@ <select id="select-language" title="<?php echo $block->escapeHtmlAttr(__('Your Language')) ?>" onchange="window.location.href=this.value" class="flags"> <?php foreach ($block->getStores() as $_lang): ?> <?php $_selected = ($_lang->getId() == $block->getCurrentStoreId()) ? ' selected="selected"' : '' ?> - <option value="<?php echo $block->escapeUrl($_lang->getCurrentUrl()) ?>" style="background-image:url('<?php echo $block->escapeUrl($block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif')) ?>');"<?php /* @noEscape */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> + <option value="<?php echo $block->escapeUrl($_lang->getCurrentUrl()) ?>" style="background-image:url('<?php echo $block->escapeUrl($block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif')); ?>');"<?php /* @noEscape */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> <?php endforeach; ?> </select> </div> -- GitLab From c6502e809e8f0c1c83eab33b6980f8b16c01294a Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 10:12:13 -0500 Subject: [PATCH 749/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../Magento/Customer/view/frontend/templates/address/edit.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index f721db9a39c..2de971bf6a9 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -213,7 +213,7 @@ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->escapeHtml($block->getRegionId())) ?>", + "defaultRegion": "<?php echo (int) $block->getRegionId() ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getCountriesWithOptionalZip(true) ?> } } -- GitLab From 8bf42ef4f7cb1cbd892a6c27390cc197e3e072f8 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Tue, 30 Aug 2016 18:12:19 +0300 Subject: [PATCH 750/838] MAGETWO-54176: Wrong quantity validation for bundle option lines - Fix static test --- .../Ui/DataProvider/Product/Form/Modifier/BundlePanel.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index f4df2038b4e..e8a02830cb8 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -588,10 +588,7 @@ class BundlePanel extends AbstractModifier 'prefer' => 'radio', 'value' => '0', 'sortOrder' => 50, - 'valueMap' => [ - 'false' => '0', - 'true' => '1' - ] + 'valueMap' => ['false' => '0', 'true' => '1'] ], ], ], -- GitLab From de93f744dc7b30de8bee72686ac1661d2a4c0865 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 10:20:17 -0500 Subject: [PATCH 751/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Eliminating @escapeNotVerified annotation --- .../Magento/Translation/view/base/templates/translate.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index f95376b1a32..92d27ff050a 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -30,7 +30,7 @@ if (versionObj.version !== '<?php /* @noEscape */ echo $version ?>') { dependencies.push( - 'text!<?php /* @noEscape */ echo Magento\Translation\Model\Js\Config::DICTIONARY_FILE_NAME ?>' + 'text!<?php /* @noEscape */ echo Magento\Translation\Model\Js\Config::DICTIONARY_FILE_NAME ?>' ); } -- GitLab From 03d9661e623b8573047ef9261ccd6ae6aa1be3da Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 10:24:11 -0500 Subject: [PATCH 752/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Eliminating @escapeNotVerified annotation --- .../view/frontend/templates/switch/languages.phtml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 cf499148e61..3b55304b280 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -9,19 +9,19 @@ /** @var \Magento\Store\Block\Switcher $block */ ?> <?php if (count($block->getStores())>1): ?> -<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> -<div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php /* @noEscape */ echo $id ?>"> +<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : '' ?> +<div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php echo $block->escapeHtmlAttr($id) ?>"> <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Language')) ?></span></strong> <div class="actions dropdown options switcher-options"> - <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php /* @noEscape */ echo $id ?>"> + <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php echo $block->escapeHtmlAttr($id) ?>"> <strong class="view-<?php echo $block->escapeHtml($block->getCurrentStoreCode()) ?>"> <span><?php echo $block->escapeHtml($block->getStoreName()) ?></span> </strong> </div> <ul class="dropdown switcher-dropdown" data-mage-init='{"dropdownDialog":{ - "appendTo":"#switcher-language<?php /* @noEscape */ echo $id ?> > .options", - "triggerTarget":"#switcher-language-trigger<?php /* @noEscape */ echo $id ?>", + "appendTo":"#switcher-language<?php echo $block->escapeJs($id) ?> > .options", + "triggerTarget":"#switcher-language-trigger<?php echo $block->escapeJs($id) ?>", "closeOnMouseLeave": false, "triggerClass":"active", "parentClass":"active", -- GitLab From 1c75cb8629782c6e07618213b97383f898fac2d7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 10:28:19 -0500 Subject: [PATCH 753/838] MAGETWO-57234: Eliminate @escapeNotVerified in Customer Module --- .../Customer/view/frontend/templates/form/register.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml index fb51e056d16..c3cb58b345f 100644 --- a/app/code/Magento/Customer/view/frontend/templates/form/register.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/form/register.phtml @@ -210,7 +210,7 @@ require([ "postcodeId": "#zip", "form": "#form-validate", "regionJson": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getRegionJson() ?>, - "defaultRegion": "<?php echo $block->escapeJs($block->escapeHtml($block->getFormData()->getRegionId())) ?>", + "defaultRegion": "<?php echo (int) $block->getFormData()->getRegionId() ?>", "countriesWithOptionalZip": <?php /* @noEscape */ echo $this->helper(\Magento\Directory\Helper\Data::class)->getCountriesWithOptionalZip(true) ?> } } -- GitLab From 2848c6365530bb354e0b002a9eeef248d1040d66 Mon Sep 17 00:00:00 2001 From: Olga Lytvynenko <olytvynenko@magento.com> Date: Tue, 30 Aug 2016 18:37:12 +0300 Subject: [PATCH 754/838] MAGETWO-54176: Wrong quantity validation for bundle option lines - Fix static test --- .../Ui/DataProvider/Product/Form/Modifier/BundlePanel.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index e8a02830cb8..50a3caaf68b 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -342,9 +342,7 @@ class BundlePanel extends AbstractModifier 'selection_price_value' => '', 'selection_qty' => '', ], - 'links' => [ - 'insertData' => '${ $.provider }:${ $.dataProvider }' - ], + 'links' => ['insertData' => '${ $.provider }:${ $.dataProvider }'], 'source' => 'product', 'addButton' => false, ], -- GitLab From 9b07dc28ce496d990d1d9575c0ec05d8bc93b061 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Tue, 30 Aug 2016 18:42:49 +0300 Subject: [PATCH 755/838] MAGETWO-57135: Product import with images not working --- .../Test/Unit/Model/Import/UploaderTest.php | 64 +++++++------------ 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php index c1657b2aab2..e8623283e16 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php @@ -68,10 +68,11 @@ class UploaderTest extends \PHPUnit_Framework_TestCase $this->readFactory = $this->getMockBuilder(\Magento\Framework\Filesystem\File\ReadFactory::class) ->disableOriginalConstructor() + ->setMethods(['create']) ->getMock(); $this->directoryMock = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\Writer::class) - ->setMethods(['writeFile', 'getRelativePath']) + ->setMethods(['writeFile', 'getRelativePath', 'isWritable', 'getAbsolutePath']) ->disableOriginalConstructor() ->getMock(); @@ -92,6 +93,7 @@ class UploaderTest extends \PHPUnit_Framework_TestCase $this->filesystem, $this->readFactory, ]) + ->setMethods(['_setUploadFile', 'save', 'getTmpDir']) ->getMock(); } @@ -100,10 +102,14 @@ class UploaderTest extends \PHPUnit_Framework_TestCase */ public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName) { + $destDir = 'var/dest/dir'; $expectedRelativeFilePath = $this->uploader->getTmpDir() . '/' . $expectedFileName; + $this->directoryMock->expects($this->once())->method('isWritable')->with($destDir)->willReturn(true); $this->directoryMock->expects($this->any())->method('getRelativePath')->with($expectedRelativeFilePath); + $this->directoryMock->expects($this->once())->method('getAbsolutePath')->with($destDir) + ->willReturn($destDir . '/' . $expectedFileName); // Check writeFile() method invoking. - $this->directoryMock->expects($this->any())->method('writeFile')->will($this->returnValue(null)); + $this->directoryMock->expects($this->any())->method('writeFile')->will($this->returnValue($expectedFileName)); // Create adjusted reader which does not validate path. $readMock = $this->getMockBuilder(\Magento\Framework\Filesystem\File\Read::class) @@ -113,59 +119,37 @@ class UploaderTest extends \PHPUnit_Framework_TestCase // Check readAll() method invoking. $readMock->expects($this->once())->method('readAll')->will($this->returnValue(null)); - $this->readFactory = $this->getMockBuilder(\Magento\Framework\Filesystem\File\ReadFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); // Check create() method invoking with expected argument. $this->readFactory->expects($this->once()) ->method('create') ->will($this->returnValue($readMock))->with($expectedHost); - - $uploaderMock = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Uploader::class) - ->setConstructorArgs([ - $this->coreFileStorageDb, - $this->coreFileStorage, - $this->imageFactory, - $this->validator, - $this->filesystem, - $this->readFactory, - ]) - ->setMethods(['_setUploadFile', 'save', 'getTmpDir']) - ->getMock(); - //Check invoking of getTmpDir(), _setUploadFile(), save() methods. - $uploaderMock->expects($this->any())->method('getTmpDir')->will($this->returnValue('')); - $uploaderMock->expects($this->once())->method('_setUploadFile')->will($this->returnSelf()); - $uploaderMock->expects($this->once())->method('save')->will($this->returnValue(['name' => null])); + $this->uploader->expects($this->any())->method('getTmpDir')->will($this->returnValue('')); + $this->uploader->expects($this->once())->method('_setUploadFile')->will($this->returnSelf()); + $this->uploader->expects($this->once())->method('save')->with($destDir . '/' . $expectedFileName) + ->willReturn(['name' => $expectedFileName]); - $uploaderMock->move($fileUrl); + $this->uploader->setDestDir($destDir); + $this->assertEquals(['name' => $expectedFileName], $this->uploader->move($fileUrl)); } public function testMoveFileName() { + $destDir = 'var/dest/dir'; $fileName = 'test_uploader_file'; $expectedRelativeFilePath = $this->uploader->getTmpDir() . '/' . $fileName; + $this->directoryMock->expects($this->once())->method('isWritable')->with($destDir)->willReturn(true); $this->directoryMock->expects($this->any())->method('getRelativePath')->with($expectedRelativeFilePath); - - $uploaderMock = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Uploader::class) - ->setConstructorArgs([ - $this->coreFileStorageDb, - $this->coreFileStorage, - $this->imageFactory, - $this->validator, - $this->filesystem, - $this->readFactory, - ]) - ->setMethods(['_setUploadFile', 'save', 'getTmpDir']) - ->getMock(); - + $this->directoryMock->expects($this->once())->method('getAbsolutePath')->with($destDir) + ->willReturn($destDir . '/' . $fileName); //Check invoking of getTmpDir(), _setUploadFile(), save() methods. - $uploaderMock->expects($this->once())->method('getTmpDir')->will($this->returnValue('')); - $uploaderMock->expects($this->once())->method('_setUploadFile')->will($this->returnSelf()); - $uploaderMock->expects($this->once())->method('save')->will($this->returnValue(['name' => null])); + $this->uploader->expects($this->once())->method('getTmpDir')->will($this->returnValue('')); + $this->uploader->expects($this->once())->method('_setUploadFile')->will($this->returnSelf()); + $this->uploader->expects($this->once())->method('save')->with($destDir . '/' . $fileName) + ->willReturn(['name' => $fileName]); - $uploaderMock->move($fileName); + $this->uploader->setDestDir($destDir); + $this->assertEquals(['name' => $fileName], $this->uploader->move($fileName)); } public function moveFileUrlDataProvider() -- GitLab From af57f9a27f17823b7b39b9e9e354282447bb56ad Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 11:04:09 -0500 Subject: [PATCH 756/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 4 ++-- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 7d99ee2318c..029162709d8 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -39,10 +39,10 @@ class Escaper * Escape string for HTML context, allowedTags will not be escaped * * @param string|array $data - * @param array $allowedTags + * @param array|null $allowedTags * @return string|array */ - public function escapeHtml($data, $allowedTags = []) + public function escapeHtml($data, $allowedTags = null) { if (is_array($data)) { $result = []; diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 2b79a7b878d..10448aae54d 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -93,8 +93,10 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'allowedTags' => ['span', 'b'], ], 'text with multiple allowed tags with allowed attribute' => [ - 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', - 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">' + . 'create an account</a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign in</a> or ' + . '<a href="%2">create an account</a>', 'allowedTags' => ['a'], ], 'text with not allowed attribute in single quotes' => [ -- GitLab From 83473ed8f244c5032e4ab59b8a1be02b1981b4e9 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 11:06:43 -0500 Subject: [PATCH 757/838] MAGETWO-55872: Eliminate @escapeNotVerified in Store, Translation and PageCache modules Eliminating @escapeNotVerified annotation --- .../view/frontend/templates/translate_inline.phtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml index 1df0995f7a2..bed01d2489e 100644 --- a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml @@ -8,9 +8,9 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> -<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css'))) ?>"/> -<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::prototype/magento.css'))) ?>"/> -<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css'))) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Theme::prototype/magento.css')) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> <script id="translate-inline-icon" type="text/x-magento-template"> <img src="<%- data.img %>" height="16" width="16" class="translate-edit-icon"> -- GitLab From 2e74692bf39f6961ac21f7773cdf1a4c3f2e18e6 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 11:23:12 -0500 Subject: [PATCH 758/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 029162709d8..b532460ccaa 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -64,12 +64,20 @@ class Escaper $wrapperElementId = uniqid(); $domDocument = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( + // @codingStandardsIgnoreStart /** - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * Handle warning and throw an exception + * + * @param string $errorNumber + * @param string $errorString + * @param string $errorFile + * @param string $errorLine + * @return void */ function ($errorNumber, $errorString, $errorFile, $errorLine) { throw new \Exception($errorString, $errorNumber); } + // @codingStandardsIgnoreEnd ); $string = mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8'); try { -- GitLab From 9e240ffb959d201eea0150c8d4c2d505caf12e4f Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Tue, 30 Aug 2016 19:31:14 +0300 Subject: [PATCH 759/838] MAGETWO-56534: CLONE - Price in cart does not update correctly when price is changed in admin. --- .../Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php index 94fe077741f..efc7f8c5b0a 100644 --- a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php +++ b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php @@ -17,8 +17,7 @@ class UpdateQuoteItems */ public function __construct( \Magento\Quote\Model\ResourceModel\Quote $resource - ) - { + ) { $this->resource = $resource; } -- GitLab From 78fe8a7e992433a3156a7eb9b1400136d871fdc5 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 11:31:26 -0500 Subject: [PATCH 760/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 7 +++++-- .../Magento/Framework/Test/Unit/EscaperTest.php | 13 +++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b532460ccaa..b53794a522d 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -118,8 +118,11 @@ class Escaper private function removeNotAllowedTags(\DOMDocument $domDocument, array $allowedTags) { $xpath = new \DOMXPath($domDocument); - $nodes = $xpath->query('//node()[name() != \'' - . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) . '\']'); + $nodes = $xpath->query( + '//node()[name() != \'' + . implode('\' and name() != \'', array_merge($allowedTags, ['html', 'body'])) + . '\']' + ); foreach ($nodes as $node) { if ($node->nodeName != '#text' && $node->nodeName != '#comment') { $node->parentNode->replaceChild($domDocument->createTextNode($node->textContent), $node); diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 10448aae54d..3390556c01d 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -105,13 +105,18 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'allowedTags' => ['span', 'b'], ], 'text with allowed and not allowed tags' => [ - 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> or <a href="%2"><span id="action">create an account</span></a>', - 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> or <a href="%2">create an account</a>', + 'data' => 'Only registered users can write reviews. Please <a href="%1">Sign in<span>three</span></a> ' + . 'or <a href="%2"><span id="action">create an account</span></a>', + 'expected' => 'Only registered users can write reviews. Please <a href="%1">Sign inthree</a> or ' + . '<a href="%2">create an account</a>', 'allowedTags' => ['a'], ], 'text with allowed and not allowed tags, with allowed and not allowed attributes' => [ - 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> <a type="some-type" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)</script>', - 'expected' => 'Some test <span>text in span tag</span> text in strong tag <a href="http://domain.com/">Click here</a>alert(1)', + 'data' => 'Some test <span>text in span tag</span> <strong>text in strong tag</strong> ' + . '<a type="some-type" href="http://domain.com/" onclick="alert(1)">Click here</a><script>alert(1)' + . '</script>', + 'expected' => 'Some test <span>text in span tag</span> text in strong tag <a href="http://domain.com/">' + . 'Click here</a>alert(1)', 'allowedTags' => ['a', 'span'], ], 'text with html comment' => [ -- GitLab From 12508d579852f91a16b11e4b45efff09b421cb4b Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 11:36:19 -0500 Subject: [PATCH 761/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b53794a522d..1bae7f6848b 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -63,8 +63,8 @@ class Escaper } $wrapperElementId = uniqid(); $domDocument = new \DOMDocument('1.0', 'UTF-8'); + // @codingStandardsIgnoreStart set_error_handler( - // @codingStandardsIgnoreStart /** * Handle warning and throw an exception * @@ -77,8 +77,8 @@ class Escaper function ($errorNumber, $errorString, $errorFile, $errorLine) { throw new \Exception($errorString, $errorNumber); } - // @codingStandardsIgnoreEnd ); + // @codingStandardsIgnoreEnd $string = mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8'); try { $domDocument->loadHTML( -- GitLab From 358ef8bf1fbe8a359355577ba089a7929f859df6 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 11:40:12 -0500 Subject: [PATCH 762/838] MAGETWO-55775: Eliminate @escapeNotVerified in Site-Related Modules --- app/code/Magento/Directory/Block/Currency.php | 2 +- .../Test/Unit/Block/CurrencyTest.php | 27 ++++++++----- .../templates/js/optional_zip_countries.phtml | 6 +-- .../view/frontend/templates/currency.phtml | 22 +++++----- .../frontend/templates/currency/switch.phtml | 6 ++- .../adminhtml/templates/template/edit.phtml | 40 +++++++++---------- .../templates/template/preview.phtml | 2 +- .../templates/page_cache_validation.phtml | 3 +- .../view/frontend/templates/javascript.phtml | 5 ++- .../frontend/templates/js/components.phtml | 1 + .../templates/page/activity_link.phtml | 6 +-- .../templates/session/activity.phtml | 27 +++++++------ .../frontend/templates/switch/flags.phtml | 7 ++-- .../frontend/templates/switch/languages.phtml | 24 +++++------ .../frontend/templates/switch/stores.phtml | 13 ++---- .../templates/translate_inline.phtml | 11 +++-- .../view/base/templates/translate.phtml | 14 ++++--- .../frontend/templates/translate_inline.phtml | 12 +++--- .../_files/whitelist/exempt_modules/ce.php | 3 -- 19 files changed, 114 insertions(+), 117 deletions(-) diff --git a/app/code/Magento/Directory/Block/Currency.php b/app/code/Magento/Directory/Block/Currency.php index c8c89d2b163..cd3064ac2cb 100644 --- a/app/code/Magento/Directory/Block/Currency.php +++ b/app/code/Magento/Directory/Block/Currency.php @@ -111,7 +111,7 @@ class Currency extends \Magento\Framework\View\Element\Template */ public function getSwitchCurrencyPostData($code) { - return $this->_postDataHelper->getPostData($this->getSwitchUrl(), ['currency' => $code]); + return $this->_postDataHelper->getPostData($this->escapeUrl($this->getSwitchUrl()), ['currency' => $code]); } /** diff --git a/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php b/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php index 9abf5a87857..cfe5e2aacd3 100644 --- a/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php +++ b/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php @@ -34,16 +34,25 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase ); $this->urlBuilder->expects($this->any())->method('getUrl')->will($this->returnArgument(0)); - /** @var \Magento\Framework\View\Element\Template\Context $context */ - $context = $this->getMock( - \Magento\Framework\View\Element\Template\Context::class, - ['getUrlBuilder'], - [], - '', - false - ); + /** @var $context \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */ + $context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class) + ->disableOriginalConstructor() + ->getMock(); $context->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilder)); + $escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) + ->disableOriginalConstructor() + ->getMock(); + $escaperMock->method('escapeUrl') + ->willReturnCallback( + function ($string) { + return 'escapeUrl' . $string; + } + ); + $context->expects($this->once()) + ->method('getEscaper') + ->willReturn($escaperMock); + /** @var \Magento\Directory\Model\CurrencyFactory $currencyFactory */ $currencyFactory = $this->getMock(\Magento\Directory\Model\CurrencyFactory::class, [], [], '', false); $this->postDataHelper = $this->getMock(\Magento\Framework\Data\Helper\PostHelper::class, [], [], '', false); @@ -63,7 +72,7 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase { $expectedResult = 'post_data'; $expectedCurrencyCode = 'test'; - $switchUrl = 'directory/currency/switch'; + $switchUrl = 'escapeUrldirectory/currency/switch'; $this->postDataHelper->expects($this->once()) ->method('getPostData') diff --git a/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml b/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml index f7d99f4a007..4b849d6abf6 100644 --- a/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml +++ b/app/code/Magento/Directory/view/adminhtml/templates/js/optional_zip_countries.phtml @@ -5,14 +5,12 @@ */ // @codingStandardsIgnoreFile -?> - -<?php /** * JS block for including Countries with Optional Zip * * @see \Magento\Backend\Block\Template */ + ?> <script> require([ @@ -21,7 +19,7 @@ require([ ], function(){ //<![CDATA[ -optionalZipCountries = <?php /* @escapeNotVerified */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?>; +optionalZipCountries = <?php /* @noEscape */ echo $this->helper('Magento\Directory\Helper\Data')->getCountriesWithOptionalZip(true) ?>; function onAddressCountryChanged (countryElement) { var zipElementId = countryElement.id.replace(/country_id/, 'postcode'); diff --git a/app/code/Magento/Directory/view/frontend/templates/currency.phtml b/app/code/Magento/Directory/view/frontend/templates/currency.phtml index 9f575624008..e5e4b0fa9f4 100644 --- a/app/code/Magento/Directory/view/frontend/templates/currency.phtml +++ b/app/code/Magento/Directory/view/frontend/templates/currency.phtml @@ -5,38 +5,36 @@ */ // @codingStandardsIgnoreFile - -?> -<?php /** * Currency switcher * - * @see \Magento\Directory\Block\Currency + * @var \Magento\Directory\Block\Currency $block */ + ?> <?php if ($block->getCurrencyCount() > 1): ?> <?php $currencies = $block->getCurrencies(); ?> <?php $currentCurrencyCode = $block->getCurrentCurrencyCode(); ?> -<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> -<div class="switcher currency switcher-currency" id="switcher-currency<?php /* @escapeNotVerified */ echo $id?>"> - <strong class="label switcher-label"><span><?php /* @escapeNotVerified */ echo __('Currency') ?></span></strong> +<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : '' ?> +<div class="switcher currency switcher-currency" id="switcher-currency<?php echo $block->escapeHtmlAttr($id) ?>"> + <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Currency')) ?></span></strong> <div class="actions dropdown options switcher-options"> - <div class="action toggle switcher-trigger" id="switcher-currency-trigger<?php /* @escapeNotVerified */ echo $id?>"> + <div class="action toggle switcher-trigger" id="switcher-currency-trigger<?php echo $block->escapeHtmlAttr($id) ?>"> <strong class="language-<?php echo $block->escapeHtml($block->getCurrentCurrencyCode()) ?>"> <span><?php echo $block->escapeHtml($currentCurrencyCode) ?> - <?php echo @$block->escapeHtml($currencies[$currentCurrencyCode]) ?></span> </strong> </div> <ul class="dropdown switcher-dropdown" data-mage-init='{"dropdownDialog":{ - "appendTo":"#switcher-currency<?php /* @escapeNotVerified */ echo $id?> > .options", - "triggerTarget":"#switcher-currency-trigger<?php /* @escapeNotVerified */ echo $id?>", + "appendTo":"#switcher-currency<?php echo $block->escapeJs($id) ?> > .options", + "triggerTarget":"#switcher-currency-trigger<?php echo $block->escapeJs($id) ?>", "closeOnMouseLeave": false, "triggerClass":"active", "parentClass":"active", "buttons":null}}'> <?php foreach ($currencies as $_code => $_name): ?> <?php if ($_code != $currentCurrencyCode): ?> - <li class="currency-<?php /* @escapeNotVerified */ echo $_code ?> switcher-option"> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getSwitchCurrencyPostData($_code); ?>'><?php /* @escapeNotVerified */ echo $_code ?> - <?php /* @escapeNotVerified */ echo $_name ?></a> + <li class="currency-<?php echo $block->escapeHtmlAttr($_code) ?> switcher-option"> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getSwitchCurrencyPostData($_code); ?>'><?php echo $block->escapeHtml($_code) ?> - <?php echo $block->escapeHtml($_name) ?></a> </li> <?php endif; ?> <?php endforeach; ?> diff --git a/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml b/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml index 92c397fb00b..f86b1c0f1fa 100644 --- a/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml +++ b/app/code/Magento/Directory/view/frontend/templates/currency/switch.phtml @@ -6,6 +6,8 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Framework\View\Element\Template $block */ + ?> -<p><?php /* @escapeNotVerified */ echo __('Your current currency is: %1.', $currency->getCode()) ?></p> -<p><a href="<?php /* @escapeNotVerified */ echo $block->getBaseUrl(); ?>" class="action continue"><span><?php /* @escapeNotVerified */ echo __('Continue') ?></span></a></p> +<p><?php echo $block->escapeHtml(__('Your current currency is: %1.', $currency->getCode())) ?></p> +<p><a href="<?php echo $block->escapeUrl($block->getBaseUrl()); ?>" class="action continue"><span><?php echo $block->escapeHtml(__('Continue')) ?></span></a></p> diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml index 26a70c64188..91b4300ddad 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml @@ -11,20 +11,20 @@ use Magento\Framework\App\TemplateTypesInterface; /** @var $block \Magento\Email\Block\Adminhtml\Template\Edit */ ?> <?php if (!$block->getEditMode()): ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getLoadUrl() ?>" method="post" id="email_template_load_form"> +<form action="<?php echo $block->escapeUrl($block->getLoadUrl()) ?>" method="post" id="email_template_load_form"> <?php echo $block->getBlockHtml('formkey')?> <fieldset class="admin__fieldset form-inline"> - <legend class="admin__legend"><span><?php /* @escapeNotVerified */ echo __('Load default template') ?></span></legend><br> + <legend class="admin__legend"><span><?php echo $block->escapeHtml(__('Load default template')) ?></span></legend><br> <div class="admin__field"> - <label class="admin__field-label" for="template_select"><?php /* @escapeNotVerified */ echo __('Template') ?></label> + <label class="admin__field-label" for="template_select"><?php echo $block->escapeHtml(__('Template')) ?></label> <div class="admin__field-control"> <select id="template_select" name="code" class="admin__control-select required-entry"> <?php foreach ($block->getTemplateOptions() as $group => $options): ?> <?php if ($group): ?> - <optgroup label="<?php echo $block->escapeHtml($group) ?>"> + <optgroup label="<?php echo $block->escapeHtmlAttr($group) ?>"> <?php endif; ?> <?php foreach ($options as $option): ?> - <option value="<?php echo $block->escapeHtml($option['value']) ?>"<?php /* @escapeNotVerified */ echo $block->getOrigTemplateCode() == $option['value'] ? ' selected="selected"' : '' ?>><?php echo $block->escapeHtml($option['label']) ?></option> + <option value="<?php echo $block->escapeHtmlAttr($option['value']) ?>"<?php /* @noEscape */ echo $block->getOrigTemplateCode() == $option['value'] ? ' selected="selected"' : '' ?>><?php echo $block->escapeHtml($option['label']) ?></option> <?php endforeach; ?> <?php if ($group): ?> </optgroup> @@ -36,24 +36,24 @@ use Magento\Framework\App\TemplateTypesInterface; <div class="admin__field required"> <span class="admin__field-label"></span> <div class="admin__field-control"> - <?php echo $block->getLoadButtonHtml() ?> + <?php /* @noEscape */ echo $block->getLoadButtonHtml() ?> </div> </div> </fieldset> </form> <?php endif ?> -<form action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" id="email_template_edit_form"> - <?php echo $block->getBlockHtml('formkey')?> +<form action="<?php echo $block->escapeUrl($block->getSaveUrl()) ?>" method="post" id="email_template_edit_form"> + <?php /* @noEscape */ echo $block->getBlockHtml('formkey')?> <input type="hidden" id="change_flag_element" name="_change_type_flag" value="" /> - <input type="hidden" id="orig_template_code" name="orig_template_code" value="<?php /* @escapeNotVerified */ echo $block->getOrigTemplateCode() ?>" /> - <?php echo $block->getFormHtml() ?> + <input type="hidden" id="orig_template_code" name="orig_template_code" value="<?php echo $block->escapeHtmlAttr($block->getOrigTemplateCode()) ?>" /> + <?php /* @noEscape */ echo $block->getFormHtml() ?> </form> -<form action="<?php /* @escapeNotVerified */ echo $block->getPreviewUrl() ?>" method="post" id="email_template_preview_form" target="_blank"> - <?php echo $block->getBlockHtml('formkey')?> +<form action="<?php echo $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="email_template_preview_form" target="_blank"> + <?php /* @noEscape */ echo $block->getBlockHtml('formkey')?> <div class="no-display"> - <input type="hidden" id="preview_type" name="type" value="<?php /* @escapeNotVerified */ echo $block->isTextType() ? 1 : 2 ?>" /> + <input type="hidden" id="preview_type" name="type" value="<?php /* @noEscape */ echo $block->isTextType() ? 1 : 2 ?>" /> <input type="hidden" id="preview_text" name="text" value="" /> <input type="hidden" id="preview_styles" name="styles" value="" /> </div> @@ -93,7 +93,7 @@ require([ this.bindEvents(); - this.renderPaths(<?php /* @escapeNotVerified */ echo $block->getCurrentlyUsedForPaths(); ?>, 'currently_used_for'); + this.renderPaths(<?php /* @noEscape */ echo $block->getCurrentlyUsedForPaths(); ?>, 'currently_used_for'); }, bindEvents: function(){ @@ -115,7 +115,7 @@ require([ }, stripTags: function () { - if(!window.confirm("<?php /* @escapeNotVerified */ echo __('Are you sure you want to strip tags?') ?>")) { + if(!window.confirm("<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure you want to strip tags?'))) ?>")) { return false; } this.unconvertedText = $('template_text').value; @@ -146,9 +146,9 @@ require([ }, preview: function() { if (this.typeChange) { - $('preview_type').value = <?php /* @escapeNotVerified */ echo TemplateTypesInterface::TYPE_TEXT ?>; + $('preview_type').value = <?php /* @noEscape */ echo TemplateTypesInterface::TYPE_TEXT ?>; } else { - $('preview_type').value = <?php /* @escapeNotVerified */ echo $block->getTemplateType() ?>; + $('preview_type').value = <?php echo (int) $block->getTemplateType() ?>; } if (typeof tinyMCE == 'undefined' || !tinyMCE.getInstanceById('template_text')) { $('preview_text').value = $('template_text').value; @@ -166,8 +166,8 @@ require([ }, deleteTemplate: function() { - if(window.confirm("<?php /* @escapeNotVerified */ echo __('Are you sure you want to delete this template?') ?>")) { - window.location.href = '<?php /* @escapeNotVerified */ echo $block->getDeleteUrl() ?>'; + if(window.confirm("<?php echo $block->escapeJs($block->escapeHtml(__('Are you sure you want to delete this template?'))) ?>")) { + window.location.href = '<?php echo $block->escapeJs($block->escapeUrl($block->getDeleteUrl())) ?>'; } }, @@ -212,7 +212,7 @@ require([ }.bind(this)); } else { alert({ - content: '<?php /* @escapeNotVerified */ echo __('The template did not load. Please review the log for details.') ?>' + content: '<?php echo $block->escapeJs($block->escapeHtml(__('The template did not load. Please review the log for details.'))) ?>' }); } }.bind(this) diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml index 53340c2e2a7..f030b675577 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/preview.phtml @@ -10,7 +10,7 @@ <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title><?php /* @escapeNotVerified */ echo __('Email Preview'); ?></title> + <title><?php echo $block->escapeHtml(__('Email Preview')); ?></title> </head> <body> <?php echo $block->getChildHtml('content') ?> diff --git a/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml b/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml index f6454d0ad9a..828a70465a2 100644 --- a/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml +++ b/app/code/Magento/PageCache/view/adminhtml/templates/page_cache_validation.phtml @@ -3,9 +3,8 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -?> -<?php /** @var \Magento\PageCache\Block\System\Config\Form\Field\Export $block */ +/** @var \Magento\PageCache\Block\System\Config\Form\Field\Export $block */ ?> <script> require(['jquery'], function($){ diff --git a/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml b/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml index 879556c41d5..830924c2691 100644 --- a/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml +++ b/app/code/Magento/PageCache/view/frontend/templates/javascript.phtml @@ -3,12 +3,13 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + +/** @var \Magento\PageCache\Block\Javascript $block */ ?> -<?php /** @var \Magento\PageCache\Block\Javascript $block */ ?> <script type="text/x-magento-init"> { "body": { - "pageCache": <?php /* @escapeNotVerified */ echo $block->getScriptOptions(); ?> + "pageCache": <?php /* @noEscape */ echo $block->getScriptOptions(); ?> } } </script> \ No newline at end of file diff --git a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml index e490a6aa049..b97c9edc8c0 100644 --- a/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml +++ b/app/code/Magento/PageCache/view/frontend/templates/js/components.phtml @@ -6,5 +6,6 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Framework\View\Element\Js\Components $block */ ?> <?php echo $block->getChildHtml() ?> diff --git a/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml b/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml index 9709002183a..ee3c962a06e 100644 --- a/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml +++ b/app/code/Magento/Security/view/adminhtml/templates/page/activity_link.phtml @@ -11,12 +11,12 @@ */ ?> <a class="link-account-activity" - href="<?php /* @escapeNotVerified */ echo $block->getUrl('security/session/activity') ?>" + href="<?php echo $block->escapeUrl($block->getUrl('security/session/activity')) ?>" id="footer_account_activity" target="_blank" data-mage-init='{"popupWindow": { - "windowURL": "<?php /* @escapeNotVerified */ echo $block->getUrl('security/session/activity') ?>", + "windowURL": "<?php echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/activity'))) ?>", "windowName": "session-activity", "width": 600, "height": 600, "top": 50, "left": 50, "resizable": 1, "scrollbars": 1}}'> - <?php /* @escapeNotVerified */ echo __('Account Activity') ?> + <?php echo $block->escapeHtml(__('Account Activity')) ?> </a> | diff --git a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml index 0dd5139f97f..d29147ae7f4 100644 --- a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml +++ b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml @@ -14,13 +14,13 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); ?> <header> <div class="page-title-wrapper"> - <h1 class="page-title" align="center"><?php /* @escapeNotVerified */ echo __('Account Activity') ?></h1> + <h1 class="page-title" align="center"><?php echo $block->escapeHtml(__('Account Activity')) ?></h1> <?php if ($block->areMultipleSessionsActive()) { - /* @escapeNotVerified */ echo __( + echo $block->escapeHtml(__( 'This administrator account is open in more than one location. ' .'Note that other locations might be different browsers or sessions on the same computer.' - ); + )); } ?> </div> </header> @@ -28,20 +28,20 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); <div class="page-content"> <?php echo $block->getLayout()->getMessagesBlock()->getGroupedHtml() ?> <div> - <div class="information-title"><?php /* @escapeNotVerified */ echo __('Concurrent session information:')?></div> + <div class="information-title"><?php echo $block->escapeHtml(__('Concurrent session information:'))?></div> <table cellspacing="0" border="1" class="information-table"> <thead> <tr> - <th><?php /* @escapeNotVerified */ echo __('IP Address') ?></th> - <th><?php /* @escapeNotVerified */ echo __('Time of session start') ?></th> + <th><?php echo $block->escapeHtml(__('IP Address')) ?></th> + <th><?php echo $block->escapeHtml(__('Time of session start')) ?></th> </tr> </thead> <tbody> <?php foreach ($sessionInfoCollection as $item):?> <tr> - <td><?php /* @escapeNotVerified */ echo $item->getFormattedIp() ?></td> - <td><?php /* @escapeNotVerified */ echo $block->formatDateTime($item->getCreatedAt()) ?></td> + <td><?php echo $block->escapeHtml($item->getFormattedIp()) ?></td> + <td><?php echo $block->escapeHtml($block->formatDateTime($item->getCreatedAt())) ?></td> </tr> <?php endforeach; @@ -55,18 +55,19 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); if ($block->areMultipleSessionsActive()): ?> data-mage-init='{"confirmRedirect":{ "message": "<?php - /* @escapeNotVerified */ echo __('Are you sure that you want to log out all other sessions?') ?>", - "url":"<?php /* @escapeNotVerified */ echo $block->getUrl('security/session/logoutAll') ?>" + echo $block->escapeJs(__('Are you sure that you want to log out all other sessions?')) ?>", + "url":"<?php + echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/logoutAll'))) ?>" }}' <?php else: ?>disabled<?php endif ?> - title="<?php /* @escapeNotVerified */ echo __('Log out all other sessions') ?>"> - <?php /* @escapeNotVerified */ echo __('Log out all other sessions') ?> + title="<?php echo $block->escapeHtmlAttr(__('Log out all other sessions')) ?>"> + <?php echo $block->escapeHtml(__('Log out all other sessions')) ?> </button> </div> <div><?php - /* @escapeNotVerified */ echo __('This computer is using IP address %1.', $block->getRemoteIp()) ?></div> + echo $block->escapeHtml(__('This computer is using IP address %1.', $block->getRemoteIp())) ?></div> </div> </div> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml index f2e6220bdef..cb151bded68 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/flags.phtml @@ -6,14 +6,15 @@ // @codingStandardsIgnoreFile +// @deprecated ?> <?php if (count($block->getStores())>1): ?> <div class="form-language"> - <label for="select-language"><?php /* @escapeNotVerified */ echo __('Your Language:') ?></label> - <select id="select-language" title="<?php /* @escapeNotVerified */ echo __('Your Language') ?>" onchange="window.location.href=this.value" class="flags"> + <label for="select-language"><?php echo $block->escapeHtml(__('Your Language:')) ?></label> + <select id="select-language" title="<?php echo $block->escapeHtmlAttr(__('Your Language')) ?>" onchange="window.location.href=this.value" class="flags"> <?php foreach ($block->getStores() as $_lang): ?> <?php $_selected = ($_lang->getId() == $block->getCurrentStoreId()) ? ' selected="selected"' : '' ?> - <option value="<?php /* @escapeNotVerified */ echo $_lang->getCurrentUrl() ?>" style="background-image:url('<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif') ?>');"<?php /* @escapeNotVerified */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> + <option value="<?php echo $block->escapeUrl($_lang->getCurrentUrl()) ?>" style="background-image:url('<?php echo $block->escapeUrl($block->getViewFileUrl('images/flags/flag_' . $_lang->getCode() . '.gif')); ?>');"<?php /* @noEscape */ echo $_selected ?>><?php echo $block->escapeHtml($_lang->getName()) ?></option> <?php endforeach; ?> </select> </div> 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 6d77072e666..3b55304b280 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/languages.phtml @@ -6,27 +6,22 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Store\Block\Switcher $block */ ?> -<?php -/** - * Language switcher template - */ -?> - <?php if (count($block->getStores())>1): ?> -<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : ''?> -<div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php /* @escapeNotVerified */ echo $id?>"> - <strong class="label switcher-label"><span><?php /* @escapeNotVerified */ echo __('Language') ?></span></strong> +<?php $id = $block->getIdModifier() ? '-' . $block->getIdModifier() : '' ?> +<div class="switcher language switcher-language" data-ui-id="language-switcher" id="switcher-language<?php echo $block->escapeHtmlAttr($id) ?>"> + <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Language')) ?></span></strong> <div class="actions dropdown options switcher-options"> - <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php /* @escapeNotVerified */ echo $id?>"> + <div class="action toggle switcher-trigger" id="switcher-language-trigger<?php echo $block->escapeHtmlAttr($id) ?>"> <strong class="view-<?php echo $block->escapeHtml($block->getCurrentStoreCode()) ?>"> <span><?php echo $block->escapeHtml($block->getStoreName()) ?></span> </strong> </div> <ul class="dropdown switcher-dropdown" data-mage-init='{"dropdownDialog":{ - "appendTo":"#switcher-language<?php /* @escapeNotVerified */ echo $id ?> > .options", - "triggerTarget":"#switcher-language-trigger<?php /* @escapeNotVerified */ echo $id ?>", + "appendTo":"#switcher-language<?php echo $block->escapeJs($id) ?> > .options", + "triggerTarget":"#switcher-language-trigger<?php echo $block->escapeJs($id) ?>", "closeOnMouseLeave": false, "triggerClass":"active", "parentClass":"active", @@ -34,8 +29,9 @@ <?php foreach ($block->getStores() as $_lang): ?> <?php if ($_lang->getId() != $block->getCurrentStoreId()): ?> <li class="view-<?php echo $block->escapeHtml($_lang->getCode()); ?> switcher-option"> - <a href="#" data-post='<?php /* @escapeNotVerified */ echo $block->getTargetStorePostData($_lang); ?>'> - <?php echo $block->escapeHtml($_lang->getName()) ?></a> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getTargetStorePostData($_lang); ?>'> + <?php echo $block->escapeHtml($_lang->getName()) ?> + </a> </li> <?php endif; ?> <?php endforeach; ?> diff --git a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml index e96ea34cdee..38c187aa273 100644 --- a/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml +++ b/app/code/Magento/Store/view/frontend/templates/switch/stores.phtml @@ -6,17 +6,11 @@ // @codingStandardsIgnoreFile -?> -<?php -/** - * Store switcher template - * - * @see \Magento\Store\Block\Store\Switcher - */ +/** @var \Magento\Store\Block\Switcher $block */ ?> <?php if (count($block->getGroups())>1): ?> <div class="switcher store switcher-store" id="switcher-store"> - <strong class="label switcher-label"><span><?php /* @escapeNotVerified */ echo __('Select Store') ?></span></strong> + <strong class="label switcher-label"><span><?php echo $block->escapeHtml(__('Select Store')) ?></span></strong> <div class="actions dropdown options switcher-options"> <?php foreach ($block->getGroups() as $_group): ?> <?php if ($_group->getId() == $block->getCurrentGroupId()): ?> @@ -37,8 +31,7 @@ <?php foreach ($block->getGroups() as $_group): ?> <?php if (!($_group->getId() == $block->getCurrentGroupId())): ?> <li class="switcher-option"> - <a href="#" - data-post='<?php /* @escapeNotVerified */ echo $block->getTargetStorePostData($_group->getDefaultStore()); ?>'> + <a href="#" data-post='<?php /* @noEscape */ echo $block->getTargetStorePostData($_group->getDefaultStore()); ?>'> <?php echo $block->escapeHtml($_group->getName()) ?> </a> </li> diff --git a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml index ab82bd0279a..4f34e9eebd9 100644 --- a/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/adminhtml/templates/translate_inline.phtml @@ -6,10 +6,10 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Framework\View\Element\Template $block */ ?> - -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('prototype/windows/themes/default.css') ?>"/> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('mage/translate-inline.css') ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> <script id="translate-inline-icon" type="text/x-magento-template"> <img src="<%- data.img %>" height="16" width="16" class="translate-edit-icon"> @@ -53,8 +53,7 @@ <% } %> </script> -<div data-role="translate-dialog" - data-mage-init='{"translateInline":{"ajaxUrl":"<?php /* @escapeNotVerified */ echo $block->getAjaxUrl() ?>"},"loader":{}}'></div> +<div data-role="translate-dialog" data-mage-init='{"translateInline":{"ajaxUrl":"<?php echo $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>"},"loader":{}}'></div> <script> require([ "jquery", @@ -63,7 +62,7 @@ require([ ], function($){ $('body').editTrigger( { - img: '<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Theme::fam_book_open.png') ?>', + img: '<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::fam_book_open.png'))) ?>', alwaysShown: true, singleElement: false } diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index 1bbf6979bf3..92d27ff050a 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -3,9 +3,11 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ + // @codingStandardsIgnoreFile + +/** @var \Magento\Translation\Block\Js $block */ ?> -<?php /** @var $block \Magento\Translation\Block\Js */ ?> <?php if ($block->dictionaryEnabled()): ?> <script> require.config({ @@ -24,10 +26,11 @@ $.initNamespaceStorage('mage-translation-file-version'); versionObj = $.localStorage.get('mage-translation-file-version'); - if (versionObj.version !== '<?php /* @escapeNotVerified */ - echo sha1($block->getTranslationFileTimestamp() . $block->getTranslationFilePath()) ?>') { + <?php $version = sha1($block->getTranslationFileTimestamp() . $block->getTranslationFilePath()); ?> + + if (versionObj.version !== '<?php /* @noEscape */ echo $version ?>') { dependencies.push( - 'text!<?php /* @escapeNotVerified */ echo Magento\Translation\Model\Js\Config::DICTIONARY_FILE_NAME?>' + 'text!<?php /* @noEscape */ echo Magento\Translation\Model\Js\Config::DICTIONARY_FILE_NAME ?>' ); } @@ -41,8 +44,7 @@ $.localStorage.set( 'mage-translation-file-version', { - version: '<?php /* @escapeNotVerified */ - echo sha1($block->getTranslationFileTimestamp() . $block->getTranslationFilePath()) ?>' + version: '<?php /* @noEscape */ echo $version ?>' } ); } else { diff --git a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml index 81e6ad79602..bed01d2489e 100644 --- a/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml +++ b/app/code/Magento/Translation/view/frontend/templates/translate_inline.phtml @@ -6,11 +6,11 @@ // @codingStandardsIgnoreFile +/** @var \Magento\Framework\View\Element\Template $block */ ?> - -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('prototype/windows/themes/default.css') ?>"/> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Theme::prototype/magento.css') ?>"/> -<link rel="stylesheet" type="text/css" href="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('mage/translate-inline.css') ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('prototype/windows/themes/default.css')) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('Magento_Theme::prototype/magento.css')) ?>"/> +<link rel="stylesheet" type="text/css" href="<?php echo $block->escapeUrl($block->getViewFileUrl('mage/translate-inline.css')) ?>"/> <script id="translate-inline-icon" type="text/x-magento-template"> <img src="<%- data.img %>" height="16" width="16" class="translate-edit-icon"> @@ -56,12 +56,12 @@ </script> <div data-role="translate-dialog" - data-mage-init='{"translateInline":{"ajaxUrl":"<?php /* @escapeNotVerified */ echo $block->getAjaxUrl() ?>"},"loader":{}}'></div> + data-mage-init='{"translateInline":{"ajaxUrl":"<?php echo $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>"},"loader":{}}'></div> <script type="text/x-magento-init"> { "body": { "editTrigger": { - "img": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('Magento_Theme::fam_book_open.png') ?>", + "img": "<?php echo $block->escapeJs($block->escapeUrl($block->getViewFileUrl('Magento_Theme::fam_book_open.png'))) ?>", "alwaysShown":true, "singleElement":false }, diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php index 077bc4138d1..c0316a43566 100644 --- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php +++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/exempt_modules/ce.php @@ -20,9 +20,7 @@ return [ 'Magento_Config', 'Magento_ConfigurableProduct', 'Magento_CurrencySymbol', - 'Magento_Directory', 'Magento_Downloadable', - 'Magento_Email', 'Magento_GiftMessage', 'Magento_GoogleAdwords', 'Magento_GoogleAnalytics', @@ -40,7 +38,6 @@ return [ 'Magento_Reports', 'Magento_Sales', 'Magento_Search', - 'Magento_Security', 'Magento_Shipping', 'Magento_Store', 'Magento_Swagger', -- GitLab From 339fd032bb51de3e44ef8026b8ddbcd29441df27 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 13:19:32 -0500 Subject: [PATCH 763/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 1bae7f6848b..54888fa9dff 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -63,22 +63,11 @@ class Escaper } $wrapperElementId = uniqid(); $domDocument = new \DOMDocument('1.0', 'UTF-8'); - // @codingStandardsIgnoreStart set_error_handler( - /** - * Handle warning and throw an exception - * - * @param string $errorNumber - * @param string $errorString - * @param string $errorFile - * @param string $errorLine - * @return void - */ - function ($errorNumber, $errorString, $errorFile, $errorLine) { + function ($errorNumber, $errorString) { throw new \Exception($errorString, $errorNumber); } ); - // @codingStandardsIgnoreEnd $string = mb_convert_encoding($data, 'HTML-ENTITIES', 'UTF-8'); try { $domDocument->loadHTML( -- GitLab From 0853d769227eca4da57c0b7bc1bc357107c0b280 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Tue, 30 Aug 2016 14:29:21 -0500 Subject: [PATCH 764/838] MAGETWO-56104: Build stablization Fixing expectation in integration test --- .../Magento/Backend/Model/Translate/InlineTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Translate/InlineTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Translate/InlineTest.php index 171f0281bb3..cc2f071e2dc 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Model/Translate/InlineTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Translate/InlineTest.php @@ -33,9 +33,11 @@ class InlineTest extends \PHPUnit_Framework_TestCase $url = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\UrlInterface::class); $url->getUrl(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE . '/ajax/translate'); $this->_translateInline->processResponseBody($body, true); - $this->assertContains( - $url->getUrl(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE . '/ajax/translate'), - $body + $expected = str_replace( + [':', '/'], + ['\u003A', '\u002F'], + $url->getUrl(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE . '/ajax/translate') ); + $this->assertContains($expected, $body); } } -- GitLab From a1fc8512bff2eeee0b5d9d4a6046cd17611c0631 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 30 Aug 2016 15:25:00 -0500 Subject: [PATCH 765/838] MAGETWO-57238: Build Stablization --- .../Customer/Block/Adminhtml/Edit/Tab/CartTest.php | 2 +- .../Customer/Block/Adminhtml/Edit/Tab/CartsTest.php | 4 ++-- .../Magento/Customer/Controller/AccountTest.php | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php index d996b8e76fb..8f6e8415d2d 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php @@ -101,7 +101,7 @@ class CartTest extends \PHPUnit_Framework_TestCase $this->assertContains("<div class=\"admin__data-grid-header admin__data-grid-toolbar\"", $html); $this->assertContains("customer_cart_gridJsObject = new varienGrid(\"customer_cart_grid\",", $html); $this->assertContains( - "backend/customer/cart_product_composite_cart/configure/customer_id/" . self::CUSTOMER_ID_VALUE, + 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fcustomer_id\u002F' . self::CUSTOMER_ID_VALUE, $html ); } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php index b3bd4aa4947..78ac6cb3c58 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php @@ -62,7 +62,7 @@ class CartsTest extends \PHPUnit_Framework_TestCase $html ); $this->assertContains("customer_cart_grid1JsObject = new varienGrid(\"customer_cart_grid1\",", $html); - $this->assertContains("backend/customer/cart_product_composite_cart/configure/website_id/1", $html); + $this->assertContains('backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fwebsite_id\u002F1', $html); } public function testGetHtmlNoCustomer() @@ -85,6 +85,6 @@ class CartsTest extends \PHPUnit_Framework_TestCase $html ); $this->assertContains("customer_cart_gridJsObject = new varienGrid(\"customer_cart_grid\",", $html); - $this->assertContains("backend/customer/cart_product_composite_cart/configure/key/", $html); + $this->assertContains('backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fupdate\u002Fkey', $html); } } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index ca0df844e7e..d80a1ee0b10 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -459,7 +459,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $this->assertContains('<div class="field field-name-firstname required">', $body); // Verify the password check box is not checked $this->assertContains('<input type="checkbox" name="change_password" id="change-password" ' - .'data-role="change-password" value="1" title="Change Password" class="checkbox" />', $body); + .'data-role="change-password" value="1" title="Change Password" class="checkbox" />', $body); } /** @@ -477,7 +477,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController // Verify the password check box is checked $this->assertContains( '<input type="checkbox" name="change_password" id="change-password" ' - .'data-role="change-password" value="1" title="Change Password" checked="checked" class="checkbox" />', + .'data-role="change-password" value="1" title="Change Password" checked="checked" class="checkbox" />', $body ); } @@ -542,7 +542,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $this->getRequest() ->setMethod('POST') ->setPostValue([ - 'form_key' => $this->_objectManager->get( + 'form_key' => $this->_objectManager->get( \Magento\Framework\Data\Form\FormKey::class)->getFormKey(), 'firstname' => 'John', 'lastname' => 'Doe', @@ -603,7 +603,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $this->getRequest() ->setMethod('POST') ->setPostValue([ - 'form_key' => $this->_objectManager->get( + 'form_key' => $this->_objectManager->get( \Magento\Framework\Data\Form\FormKey::class)->getFormKey(), 'firstname' => 'John', 'lastname' => 'Doe', @@ -633,7 +633,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController $this->getRequest() ->setMethod('POST') ->setPostValue([ - 'form_key' => $this->_objectManager->get( + 'form_key' => $this->_objectManager->get( \Magento\Framework\Data\Form\FormKey::class)->getFormKey(), 'firstname' => 'John', 'lastname' => 'Doe', -- GitLab From 4bb9f5be1ef530222c89465829a398628f321f4c Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Tue, 30 Aug 2016 16:48:30 -0500 Subject: [PATCH 766/838] MAGETWO-57270: Create unit test to cover change to escapeHtml - Added another test case. --- .../Framework/Test/Unit/EscaperTest.php | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 3390556c01d..59b3c3be79b 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -50,15 +50,12 @@ class EscaperTest extends \PHPUnit_Framework_TestCase /** * @covers \Magento\Framework\Escaper::escapeHtml + * @dataProvider escapeHtmlInvalidDataProvider */ - public function testEscapeHtmlWithInvalidData() + public function testEscapeHtmlWithInvalidData($data, $expected, $allowedTags = []) { - $data = '<span><script>some text in tags</script></span>'; - $expected = ''; - $allowedTags = ['script', 'span']; $this->loggerMock->expects($this->once()) - ->method('critical') - ->with('The following tag(s) are not allowed: script'); + ->method('critical'); $actual = $this->_escaper->escapeHtml($data, $allowedTags); $this->assertEquals($expected, $actual); } @@ -137,6 +134,25 @@ class EscaperTest extends \PHPUnit_Framework_TestCase ]; } + /** + * @return array + */ + public function escapeHtmlInvalidDataProvider() + { + return [ + 'text with allowed script tag' => [ + 'data' => '<span><script>some text in tags</script></span>', + 'expected' => '', + 'allowedTags' => ['span', 'script'], + ], + 'text with invalid html' => [ + 'data' => '<spa>n id="id1">Some string</span>', + 'expected' => '', + 'allowedTags' => ['span'], + ], + ]; + } + /** * @covers \Magento\Framework\Escaper::escapeUrl */ -- GitLab From 8488aa7abbd9b277fdcb335f9ecf76c1f5f16cdc Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Wed, 31 Aug 2016 11:42:15 +0300 Subject: [PATCH 767/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../Model/Product/Type/ConfigurableTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 817effc369d..59d828baa2d 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 @@ -301,8 +301,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $product->addCustomOption('attributes', serialize([$attribute['attribute_id'] => $optionValueId])); $info = $this->model->getSelectedAttributesInfo($product); - $this->assertEquals('Test Configurable', $info['label']); - $this->assertEquals('Option 1', $info['value']); + $this->assertEquals('Test Configurable', $info[0]['label']); + $this->assertEquals('Option 1', $info[0]['value']); } /** @@ -323,8 +323,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $attribute->getProductAttribute()->setStoreLabel('store label'); $info = $this->model->getSelectedAttributesInfo($this->product); - $this->assertEquals('store label', $info['label']); - $this->assertEquals('Option 1', $info['value']); + $this->assertEquals('store label', $info[0]['label']); + $this->assertEquals('Option 1', $info[0]['value']); } /** @@ -371,8 +371,8 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase $result = $this->model->getOrderOptions($product); $this->assertArrayHasKey('info_buyRequest', $result); $this->assertArrayHasKey('attributes_info', $result); - $this->assertEquals('Test Configurable', $result['attributes_info']['label']); - $this->assertEquals('Option 1', $result['attributes_info']['value']); + $this->assertEquals('Test Configurable', $result['attributes_info'][0]['label']); + $this->assertEquals('Option 1', $result['attributes_info'][0]['value']); $this->assertArrayHasKey('product_calculations', $result); $this->assertArrayHasKey('shipment_type', $result); $this->assertEquals( -- GitLab From a049a361d9a3ac38335ecd73b810d025f759361a Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Wed, 31 Aug 2016 11:46:18 +0300 Subject: [PATCH 768/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- .../Console/Command/ImagesResizeCommand.php | 2 +- lib/internal/Magento/Framework/App/Area.php | 21 ++++++++++++++++++ lib/internal/Magento/Framework/App/State.php | 22 +++++++++++++++++++ .../Framework/Setup/SampleData/Executor.php | 2 +- setup/src/Magento/Setup/Model/Installer.php | 2 +- 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php b/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php index 076184466d5..abfdc4bdb75 100644 --- a/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php +++ b/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php @@ -71,7 +71,7 @@ class ImagesResizeCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->appState->setAreaCode('catalog'); + $this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); /** @var ProductCollection $productCollection */ $productCollection = $this->productCollectionFactory->create(); diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php index 20dbbe01d9f..b370cb78b71 100644 --- a/lib/internal/Magento/Framework/App/Area.php +++ b/lib/internal/Magento/Framework/App/Area.php @@ -29,6 +29,16 @@ class Area implements \Magento\Framework\App\AreaInterface */ const PARAM_AREA = 'area'; + /** + * List of existing areas + * + * @var array + */ + private static $existingAreas = [ + self::AREA_GLOBAL, self::AREA_FRONTEND, self::AREA_ADMIN, self::AREA_ADMINHTML, + self::AREA_DOC, self::AREA_CRONTAB, self::AREA_WEBAPI_REST, self::AREA_WEBAPI_SOAP + ]; + /** * Array of area loaded parts * @@ -160,6 +170,17 @@ class Area implements \Magento\Framework\App\AreaInterface } } + /** + * Check that area exists + * + * @param $areaCode + * @return bool + */ + public static function doesAreaExist($areaCode) + { + return in_array($areaCode, self::$existingAreas); + } + /** * Analyze user-agent information to override custom design settings * diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index 66431fe2be8..d498ff1f357 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -7,6 +7,8 @@ */ namespace Magento\Framework\App; +use Magento\Framework\App\Area; + class State { /** @@ -118,6 +120,8 @@ class State */ public function setAreaCode($code) { + $this->checkAreaCode($code); + if (isset($this->_areaCode)) { throw new \Magento\Framework\Exception\LocalizedException( new \Magento\Framework\Phrase('Area code is already set') @@ -164,6 +168,8 @@ class State */ public function emulateAreaCode($areaCode, $callback, $params = []) { + $this->checkAreaCode($areaCode); + $currentArea = $this->_areaCode; $this->_areaCode = $areaCode; $this->_isAreaCodeEmulated = true; @@ -178,4 +184,20 @@ class State $this->_isAreaCodeEmulated = false; return $result; } + + /** + * Check that area code exists + * + * @param $areaCode + * @throws \Magento\Framework\Exception\LocalizedException + * @return void + */ + private function checkAreaCode($areaCode) + { + if (!Area::doesAreaExist($areaCode)) { + throw new \Magento\Framework\Exception\LocalizedException( + new \Magento\Framework\Phrase('Area code "%1" does not exist', [$areaCode]) + ); + } + } } diff --git a/lib/internal/Magento/Framework/Setup/SampleData/Executor.php b/lib/internal/Magento/Framework/Setup/SampleData/Executor.php index 844c263918a..2f61f54f391 100644 --- a/lib/internal/Magento/Framework/Setup/SampleData/Executor.php +++ b/lib/internal/Magento/Framework/Setup/SampleData/Executor.php @@ -47,7 +47,7 @@ class Executor public function exec(InstallerInterface $installer) { try { - $this->appState->emulateAreaCode('setup', [$installer, 'install']); + $this->appState->emulateAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL, [$installer, 'install']); $this->state->setInstalled(); } catch (\Exception $e) { $this->state->setError(); diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index 74d5f9664cd..636b87c490d 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -899,7 +899,7 @@ class Installer $userConfig = new StoreConfigurationDataMapper(); /** @var \Magento\Framework\App\State $appState */ $appState = $this->objectManagerProvider->get()->get(\Magento\Framework\App\State::class); - $appState->setAreaCode('setup'); + $appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); $configData = $userConfig->getConfigData($data); if (count($configData) === 0) { return; -- GitLab From b0eea2ea4b1ac81fa1c897aadeaae5021880ede5 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Wed, 31 Aug 2016 12:00:43 +0300 Subject: [PATCH 769/838] MAGETWO-57397: Update gallery entry via API doesn't work - for mainline --- .../Catalog/Model/Product/Gallery/GalleryManagement.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php index 54ca1948053..950e2253a95 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/GalleryManagement.php @@ -96,7 +96,9 @@ class GalleryManagement implements \Magento\Catalog\Api\ProductAttributeMediaGal foreach ($existingMediaGalleryEntries as $key => $existingEntry) { if ($existingEntry->getId() == $entry->getId()) { $found = true; - $entry->setId(null); + if ($entry->getFile()) { + $entry->setId(null); + } $existingMediaGalleryEntries[$key] = $entry; break; } -- GitLab From 3aa7a86f5221d30cfb597c9ddea600d84d491546 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Wed, 31 Aug 2016 12:34:47 +0300 Subject: [PATCH 770/838] MAGETWO-57129: Identity Service fix --- .../Test/Unit/IdentityServiceTest.php | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 lib/internal/Magento/Framework/DataObject/Test/Unit/IdentityServiceTest.php diff --git a/lib/internal/Magento/Framework/DataObject/Test/Unit/IdentityServiceTest.php b/lib/internal/Magento/Framework/DataObject/Test/Unit/IdentityServiceTest.php deleted file mode 100644 index b9f326e79f8..00000000000 --- a/lib/internal/Magento/Framework/DataObject/Test/Unit/IdentityServiceTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\DataObject\Test\Unit; - -use Ramsey\Uuid\Uuid; - -class IdentityServiceTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Magento\Framework\DataObject\IdentityService - */ - private $identityService; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $ramseyFactoryMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - private $uuidMock; - - protected function setUp() - { - $this->ramseyFactoryMock = $this->getMock(\Ramsey\Uuid\UuidFactory::class, [], [], '', false); - $this->uuidMock = $this->getMock(\Ramsey\Uuid\Uuid::class, [], [], '', false); - $this->identityService = new \Magento\Framework\DataObject\IdentityService( - $this->ramseyFactoryMock - ); - } - - public function testGenerateId() - { - $this->ramseyFactoryMock->expects($this->once())->method('uuid4')->willReturn($this->uuidMock); - $this->uuidMock->expects($this->once())->method('toString')->willReturn('string'); - $this->assertEquals('string', $this->identityService->generateId()); - } - - public function testGenerateIdForData() - { - $this->ramseyFactoryMock - ->expects($this->once()) - ->method('uuid3') - ->with(Uuid::NAMESPACE_DNS, 'name') - ->willReturn($this->uuidMock); - $this->uuidMock->expects($this->once())->method('toString')->willReturn('string'); - $this->assertEquals('string', $this->identityService->generateIdForData('name')); - } -} -- GitLab From e5963a618142e370a4f1cd5ea3f6031a3cf6fba0 Mon Sep 17 00:00:00 2001 From: Oleksandr Radchenko <oradchenko@magento.com> Date: Wed, 31 Aug 2016 14:30:51 +0300 Subject: [PATCH 771/838] MAGETWO-57397: Update gallery entry via API doesn't work - for mainline --- .../Test/Unit/Model/Product/Gallery/GalleryManagementTest.php | 1 + 1 file changed, 1 insertion(+) 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 ea2ddca59f4..fb2d197749e 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 @@ -200,6 +200,7 @@ class GalleryManagementTest extends \PHPUnit_Framework_TestCase $this->productMock->expects($this->once())->method('getMediaGalleryEntries') ->willReturn([$existingEntryMock]); $entryMock->expects($this->once())->method('getId')->willReturn($entryId); + $entryMock->expects($this->once())->method('getFile')->willReturn("base64"); $entryMock->expects($this->once())->method('setId')->with(null); $this->productMock->expects($this->once())->method('setMediaGalleryEntries') -- GitLab From c849bc6e2abf7a23e085d9e5567ab52de3ff24c9 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Wed, 31 Aug 2016 14:40:10 +0300 Subject: [PATCH 772/838] MAGETWO-57129: Identity Service fix --- .../Framework/DataObject/IdentityService.php | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/lib/internal/Magento/Framework/DataObject/IdentityService.php b/lib/internal/Magento/Framework/DataObject/IdentityService.php index b16d0a249ea..6088a23e67a 100644 --- a/lib/internal/Magento/Framework/DataObject/IdentityService.php +++ b/lib/internal/Magento/Framework/DataObject/IdentityService.php @@ -1,45 +1,45 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Framework\DataObject; - -use Ramsey\Uuid\Uuid; - -/** - * Class IdentityService - */ -class IdentityService implements IdentityGeneratorInterface -{ - /** - * @var \Ramsey\Uuid\UuidFactoryInterface - */ - private $uuidFactory; - - /** - * IdentityService constructor. - */ - public function __construct( - ) { - $this->uuidFactory = new \Ramsey\Uuid\UuidFactory(); - } - - /** - * @inheritDoc - */ - public function generateId() - { - $uuid = $this->uuidFactory->uuid4(); - return $uuid->toString(); - } - - /** - * @inheritDoc - */ - public function generateIdForData($data) - { - $uuid = $this->uuidFactory->uuid3(Uuid::NAMESPACE_DNS, $data); - return $uuid->toString(); - } -} +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\DataObject; + +use Ramsey\Uuid\Uuid; + +/** + * Class IdentityService + */ +class IdentityService implements IdentityGeneratorInterface +{ + /** + * @var \Ramsey\Uuid\UuidFactoryInterface + */ + private $uuidFactory; + + /** + * IdentityService constructor. + */ + public function __construct( + ) { + $this->uuidFactory = new \Ramsey\Uuid\UuidFactory(); + } + + /** + * @inheritDoc + */ + public function generateId() + { + $uuid = $this->uuidFactory->uuid4(); + return $uuid->toString(); + } + + /** + * @inheritDoc + */ + public function generateIdForData($data) + { + $uuid = $this->uuidFactory->uuid3(Uuid::NAMESPACE_DNS, $data); + return $uuid->toString(); + } +} -- GitLab From e2c195f77ee114c57326f9afc8f1163fd1e7f89c Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Wed, 31 Aug 2016 14:57:20 +0300 Subject: [PATCH 773/838] MAGETWO-57129: Identity Service fix --- lib/internal/Magento/Framework/DataObject/IdentityService.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/DataObject/IdentityService.php b/lib/internal/Magento/Framework/DataObject/IdentityService.php index 6088a23e67a..a58ac40b97b 100644 --- a/lib/internal/Magento/Framework/DataObject/IdentityService.php +++ b/lib/internal/Magento/Framework/DataObject/IdentityService.php @@ -20,8 +20,8 @@ class IdentityService implements IdentityGeneratorInterface /** * IdentityService constructor. */ - public function __construct( - ) { + public function __construct() + { $this->uuidFactory = new \Ramsey\Uuid\UuidFactory(); } -- GitLab From ea7596f8ca8c5284cd281c7344b4db3ab7e0254e Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Wed, 31 Aug 2016 15:04:48 +0300 Subject: [PATCH 774/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- .../Command/ProductAttributesCleanUp.php | 2 +- .../Command/ImagesResizeCommandTest.php | 7 +++-- .../Framework/View/Element/TemplateTest.php | 16 +++++----- .../Magento/Theme/Model/View/DesignTest.php | 4 +-- lib/internal/Magento/Framework/App/Area.php | 2 +- lib/internal/Magento/Framework/App/State.php | 2 +- .../Framework/App/Test/Unit/AreaTest.php | 6 ++++ .../Framework/App/Test/Unit/StateTest.php | 29 +++++++++++++------ 8 files changed, 42 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php b/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php index d1b938296f9..25364844e3a 100644 --- a/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php +++ b/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php @@ -78,7 +78,7 @@ class ProductAttributesCleanUp extends \Symfony\Component\Console\Command\Comman protected function execute(InputInterface $input, OutputInterface $output) { $output->setDecorated(true); - $this->appState->setAreaCode('catalog'); + $this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); $connection = $this->attributeResource->getConnection(); $attributeTables = $this->getAttributeTables(); diff --git a/app/code/Magento/Catalog/Test/Unit/Console/Command/ImagesResizeCommandTest.php b/app/code/Magento/Catalog/Test/Unit/Console/Command/ImagesResizeCommandTest.php index cd350316c10..d87837bebac 100644 --- a/app/code/Magento/Catalog/Test/Unit/Console/Command/ImagesResizeCommandTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Console/Command/ImagesResizeCommandTest.php @@ -14,6 +14,7 @@ use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductColl use Magento\Framework\App\State as AppState; use Magento\Framework\Exception\NoSuchEntityException; use Symfony\Component\Console\Tester\CommandTester; +use \Magento\Framework\App\Area; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -79,7 +80,7 @@ class ImagesResizeCommandTest extends \PHPUnit_Framework_TestCase { $this->appState->expects($this->once()) ->method('setAreaCode') - ->with('catalog') + ->with(Area::AREA_GLOBAL) ->willReturnSelf(); $this->productCollection->expects($this->once()) @@ -101,7 +102,7 @@ class ImagesResizeCommandTest extends \PHPUnit_Framework_TestCase $this->appState->expects($this->once()) ->method('setAreaCode') - ->with('catalog') + ->with(Area::AREA_GLOBAL) ->willReturnSelf(); $this->productCollection->expects($this->once()) @@ -142,7 +143,7 @@ class ImagesResizeCommandTest extends \PHPUnit_Framework_TestCase $this->appState->expects($this->once()) ->method('setAreaCode') - ->with('catalog') + ->with(Area::AREA_GLOBAL) ->willReturnSelf(); $this->productCollection->expects($this->once()) diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Element/TemplateTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Element/TemplateTest.php index 050b53818ce..813273c97b6 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/View/Element/TemplateTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/View/Element/TemplateTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Framework\View\Element; +use \Magento\Framework\App\Area; + class TemplateTest extends \PHPUnit_Framework_TestCase { /** @@ -52,16 +54,12 @@ class TemplateTest extends \PHPUnit_Framework_TestCase $this->assertEquals('frontend', $this->_block->getArea()); \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\App\State::class - )->setAreaCode( - 'some_area' - ); - $this->assertEquals('some_area', $this->_block->getArea()); + )->setAreaCode(Area::AREA_ADMINHTML); + $this->assertEquals(Area::AREA_ADMINHTML, $this->_block->getArea()); \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\App\State::class - )->setAreaCode( - 'another_area' - ); - $this->assertEquals('another_area', $this->_block->getArea()); + )->setAreaCode(Area::AREA_GLOBAL); + $this->assertEquals(Area::AREA_GLOBAL, $this->_block->getArea()); } /** @@ -71,7 +69,7 @@ class TemplateTest extends \PHPUnit_Framework_TestCase public function testToHtml() { \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) - ->setAreaCode('any area'); + ->setAreaCode(Area::AREA_GLOBAL); $this->assertEmpty($this->_block->toHtml()); $this->_block->setTemplate(uniqid('invalid_filename.phtml')); $this->assertEmpty($this->_block->toHtml()); diff --git a/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php b/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php index 59960323665..4992f3d8caf 100644 --- a/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Theme/Model/View/DesignTest.php @@ -85,8 +85,8 @@ class DesignTest extends \PHPUnit_Framework_TestCase { $this->assertEquals(\Magento\Framework\View\DesignInterface::DEFAULT_AREA, $this->_model->getArea()); \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\App\State::class) - ->setAreaCode('test'); - $this->assertEquals('test', $this->_model->getArea()); + ->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML); + $this->assertEquals(\Magento\Framework\App\Area::AREA_ADMINHTML, $this->_model->getArea()); } public function testSetDesignTheme() diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php index b370cb78b71..013e2fa6a88 100644 --- a/lib/internal/Magento/Framework/App/Area.php +++ b/lib/internal/Magento/Framework/App/Area.php @@ -173,7 +173,7 @@ class Area implements \Magento\Framework\App\AreaInterface /** * Check that area exists * - * @param $areaCode + * @param string $areaCode * @return bool */ public static function doesAreaExist($areaCode) diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index d498ff1f357..47ad2350a4d 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -188,7 +188,7 @@ class State /** * Check that area code exists * - * @param $areaCode + * @param string $areaCode * @throws \Magento\Framework\Exception\LocalizedException * @return void */ diff --git a/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php b/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php index a280658ca2a..2416ba6f9b8 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php @@ -315,4 +315,10 @@ class AreaTest extends \PHPUnit_Framework_TestCase ->with($exception); $this->object->detectDesign($requestMock); } + + public function testDoesAreaExist() + { + $this->assertTrue($this->object->doesAreaExist(Area::AREA_FRONTEND)); + $this->assertFalse($this->object->doesAreaExist('any area')); + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php b/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php index c68d8eb30ae..c10f7d66d3d 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php @@ -8,6 +8,8 @@ namespace Magento\Framework\App\Test\Unit; +use \Magento\Framework\App\Area; + class StateTest extends \PHPUnit_Framework_TestCase { /** @@ -33,11 +35,11 @@ class StateTest extends \PHPUnit_Framework_TestCase public function testSetAreaCode() { - $areaCode = 'some code'; + $areaCode = Area::AREA_FRONTEND; $this->scopeMock->expects($this->once())->method('setCurrentScope')->with($areaCode); $this->model->setAreaCode($areaCode); $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class); - $this->model->setAreaCode('any code'); + $this->model->setAreaCode(Area::AREA_ADMINHTML); } public function testGetAreaCodeException() @@ -49,7 +51,7 @@ class StateTest extends \PHPUnit_Framework_TestCase public function testGetAreaCode() { - $areaCode = 'some code'; + $areaCode = Area::AREA_FRONTEND; $this->scopeMock->expects($this->once())->method('setCurrentScope')->with($areaCode); $this->model->setAreaCode($areaCode); $this->assertEquals($areaCode, $this->model->getAreaCode()); @@ -57,8 +59,8 @@ class StateTest extends \PHPUnit_Framework_TestCase public function testEmulateAreaCode() { - $areaCode = 'original code'; - $emulatedCode = 'emulated code'; + $areaCode = Area::AREA_FRONTEND; + $emulatedCode = Area::AREA_ADMINHTML; $this->scopeMock->expects($this->once())->method('setCurrentScope')->with($areaCode); $this->model->setAreaCode($areaCode); $this->assertEquals( @@ -75,8 +77,8 @@ class StateTest extends \PHPUnit_Framework_TestCase public function testIsAreaCodeEmulated() { - $areaCode = 'original code'; - $emulatedCode = 'emulated code'; + $areaCode = Area::AREA_ADMINHTML; + $emulatedCode = Area::AREA_FRONTEND; $this->scopeMock->expects($this->once())->method('setCurrentScope')->with($areaCode); $this->model->setAreaCode($areaCode); $this->assertFalse( @@ -109,8 +111,8 @@ class StateTest extends \PHPUnit_Framework_TestCase */ public function testEmulateAreaCodeException() { - $areaCode = 'original code'; - $emulatedCode = 'emulated code'; + $areaCode = Area::AREA_FRONTEND; + $emulatedCode = Area::AREA_ADMINHTML; $this->scopeMock->expects($this->once())->method('setCurrentScope')->with($areaCode); $this->model->setAreaCode($areaCode); $this->model->emulateAreaCode($emulatedCode, [$this, 'emulateAreaCodeCallbackException']); @@ -158,4 +160,13 @@ class StateTest extends \PHPUnit_Framework_TestCase "unknown mode" ); } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Area code "any code" does not exist + */ + public function testCheckAreaCodeException() + { + $this->model->setAreaCode('any code'); + } } -- GitLab From b989c491915d3679a87dc13418d5a422b29799c0 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 31 Aug 2016 08:49:10 -0500 Subject: [PATCH 775/838] MAGETWO-57238: Build Stablization --- .../Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php | 3 ++- .../Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php index 8f6e8415d2d..7ddf10e58bd 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php @@ -101,7 +101,8 @@ class CartTest extends \PHPUnit_Framework_TestCase $this->assertContains("<div class=\"admin__data-grid-header admin__data-grid-toolbar\"", $html); $this->assertContains("customer_cart_gridJsObject = new varienGrid(\"customer_cart_grid\",", $html); $this->assertContains( - 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fcustomer_id\u002F' . self::CUSTOMER_ID_VALUE, + 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fcustomer_id\u002F' . + self::CUSTOMER_ID_VALUE, $html ); } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php index 78ac6cb3c58..8db8a623eea 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartsTest.php @@ -62,7 +62,10 @@ class CartsTest extends \PHPUnit_Framework_TestCase $html ); $this->assertContains("customer_cart_grid1JsObject = new varienGrid(\"customer_cart_grid1\",", $html); - $this->assertContains('backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fwebsite_id\u002F1', $html); + $this->assertContains( + 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fwebsite_id\u002F1', + $html + ); } public function testGetHtmlNoCustomer() -- GitLab From a86eda34f882d9254f707a09f9e209b5c54ee632 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 31 Aug 2016 17:27:08 +0300 Subject: [PATCH 776/838] MAGETWO-55184: [GitHub #5526]Selected category is not added to Cart Price Rule condition due to JS error --- .../Adminhtml/Promo/Quote/Edit/Tab/Actions.php | 2 +- .../Controller/Adminhtml/Promo/Quote/Edit.php | 18 +++++++++--------- .../Adminhtml/Promo/Quote/NewActionHtml.php | 2 +- .../Model/Rule/Condition/Product/Combine.php | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Actions.php b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Actions.php index a5536662608..396eee2ddd9 100644 --- a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Actions.php +++ b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/Tab/Actions.php @@ -176,7 +176,7 @@ class Actions extends \Magento\Backend\Block\Widget\Form\Generic implements $actionsFieldSetId = $model->getActionsFieldSetId($formName); $newChildUrl = $this->getUrl( - 'sales_rule/promo_quote/newActionHtml/form/rule_actions_fieldset_' . $actionsFieldSetId, + 'sales_rule/promo_quote/newActionHtml/form/' . $actionsFieldSetId, ['form_namespace' => $formName] ); diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php index e1fc0fb751e..8fca36fc673 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php @@ -55,6 +55,15 @@ class Edit extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote $this->_redirect('sales_rule/*'); return; } + $model->getConditions()->setFormName('sales_rule_form'); + $model->getConditions()->setJsFormObject( + $model->getConditionsFieldSetId($model->getConditions()->getFormName()) + ); + $model->getActions()->setFormName('sales_rule_form'); + $model->getActions()->setJsFormObject( + $model->getActionsFieldSetId($model->getActions()->getFormName()) + ); + $resultPage->getLayout()->getBlock('promo_sales_rule_edit_tab_coupons')->setCanShow(true); } @@ -65,15 +74,6 @@ class Edit extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote $model->addData($data); } - $model->getConditions()->setFormName('sales_rule_form'); - $model->getConditions()->setJsFormObject( - $model->getConditionsFieldSetId($model->getConditions()->getFormName()) - ); - $model->getActions()->setFormName('sales_rule_form'); - $model->getActions()->setJsFormObject( - $model->getActionsFieldSetId($model->getActions()->getFormName()) - ); - $this->_initAction(); $this->_addBreadcrumb($id ? __('Edit Rule') : __('New Rule'), $id ? __('Edit Rule') : __('New Rule')); diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php index 61a674bc0a0..b56dae4737f 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php @@ -16,7 +16,7 @@ class NewActionHtml extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote public function execute() { $id = $this->getRequest()->getParam('id'); - $formName = $this->getRequest()->getParam('form_namespace'); + $formName = $this->getRequest()->getParam('form'); $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type'))); $type = $typeArr[0]; diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php index 1ac904309a0..620c4bd70d4 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php +++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Combine.php @@ -42,12 +42,12 @@ class Combine extends \Magento\Rule\Model\Condition\Combine foreach ($productAttributes as $code => $label) { if (strpos($code, 'quote_item_') === 0) { $iAttributes[] = [ - 'value' => \Magento\SalesRule\Model\Rule\Condition\Product::class . $code, + 'value' => \Magento\SalesRule\Model\Rule\Condition\Product::class . '|' . $code, 'label' => $label, ]; } else { $pAttributes[] = [ - 'value' => \Magento\SalesRule\Model\Rule\Condition\Product::class . $code, + 'value' => \Magento\SalesRule\Model\Rule\Condition\Product::class . '|' . $code, 'label' => $label, ]; } -- GitLab From 8fd1e17d5d3a2a86219e8cc14d3b0e4a0d4eab80 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Wed, 31 Aug 2016 10:27:23 -0500 Subject: [PATCH 777/838] MAGETWO-57836: Make \Magento\Framework\Escaper::escapeJs() generate valid Json string --- lib/internal/Magento/Framework/Escaper.php | 7 +- .../Framework/Test/Unit/EscaperTest.php | 122 ++++++++++++++++-- 2 files changed, 115 insertions(+), 14 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 493d517d83e..16d7c57a083 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -234,7 +234,12 @@ class Escaper return preg_replace_callback( '/[^a-z0-9,\._]/iSu', function ($matches) { - return sprintf('\\u%04s', strtoupper(bin2hex($matches[0]))); + $chr = $matches[0]; + if (strlen($chr) != 1) { + $chr = mb_convert_encoding($chr, 'UTF-16BE', 'UTF-8'); + $chr = ($chr === false) ? '' : $chr; + } + return sprintf('\\u%04s', strtoupper(bin2hex($chr))); }, $string ); diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 59b3c3be79b..58b45a72f1a 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -16,7 +16,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Framework\Escaper */ - protected $_escaper = null; + protected $escaper = null; /** * @var \Magento\Framework\ZendEscaper @@ -30,12 +30,108 @@ class EscaperTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->_escaper = new Escaper(); + $this->escaper = new Escaper(); $this->zendEscaper = new \Magento\Framework\ZendEscaper(); $this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class); $objectManagerHelper = new ObjectManager($this); - $objectManagerHelper->setBackwardCompatibleProperty($this->_escaper, 'escaper', $this->zendEscaper); - $objectManagerHelper->setBackwardCompatibleProperty($this->_escaper, 'logger', $this->loggerMock); + $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'escaper', $this->zendEscaper); + $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'logger', $this->loggerMock); + } + + /** + * Convert a Unicode Codepoint to a literal UTF-8 character. + * + * @param int $codepoint Unicode codepoint in hex notation + * @return string UTF-8 literal string + */ + protected function codepointToUtf8($codepoint) + { + if ($codepoint < 0x80) { + return chr($codepoint); + } + if ($codepoint < 0x800) { + return chr($codepoint >> 6 & 0x3f | 0xc0) + . chr($codepoint & 0x3f | 0x80); + } + if ($codepoint < 0x10000) { + return chr($codepoint >> 12 & 0x0f | 0xe0) + . chr($codepoint >> 6 & 0x3f | 0x80) + . chr($codepoint & 0x3f | 0x80); + } + if ($codepoint < 0x110000) { + return chr($codepoint >> 18 & 0x07 | 0xf0) + . chr($codepoint >> 12 & 0x3f | 0x80) + . chr($codepoint >> 6 & 0x3f | 0x80) + . chr($codepoint & 0x3f | 0x80); + } + throw new \Exception('Codepoint requested outside of Unicode range'); + } + + public function testEscapeJsEscapesOwaspRecommendedRanges() + { + $immune = [',', '.', '_']; // Exceptions to escaping ranges + for ($chr=0; $chr < 0xFF; $chr++) { + if ($chr >= 0x30 && $chr <= 0x39 + || $chr >= 0x41 && $chr <= 0x5A + || $chr >= 0x61 && $chr <= 0x7A + ) { + $literal = $this->codepointToUtf8($chr); + $this->assertEquals($literal, $this->escaper->escapeJs($literal)); + } else { + $literal = $this->codepointToUtf8($chr); + if (in_array($literal, $immune)) { + $this->assertEquals($literal, $this->escaper->escapeJs($literal)); + } else { + $this->assertNotEquals( + $literal, + $this->escaper->escapeJs($literal), + $literal . ' should be escaped!' + ); + } + } + } + } + + /** + * @param string $data + * @param string $expected + * @dataProvider escapeJsDataProvider + */ + public function testEscapeJs($data, $expected) + { + $this->assertEquals($expected, $this->escaper->escapeJs($data)); + } + + public function escapeJsDataProvider() + { + return [ + 'zero length string' => ['', ''], + 'only digits' => ['123', '123'], + '<' => ['<', '\u003C'], + '>' => ['>', '\\u003E'], + '\'' => ['\'', '\\u0027'], + '"' => ['"', '\\u0022'], + '&' => ['&', '\\u0026'], + 'Characters beyond ASCII value 255 to unicode escape' => ['Ä€', '\\u0100'], + 'Characters beyond Unicode BMP to unicode escape' => ["\xF0\x90\x80\x80", '\\uD800DC00'], + /* Immune chars excluded */ + ',' => [',', ','], + '.' => ['.', '.'], + '_' => ['_', '_'], + /* Basic alnums exluded */ + 'a' => ['a', 'a'], + 'A' => ['A', 'A'], + 'z' => ['z', 'z'], + 'Z' => ['Z', 'Z'], + '0' => ['0', '0'], + '9' => ['9', '9'], + /* Basic control characters and null */ + "\r" => ["\r", '\\u000D'], + "\n" => ["\n", '\\u000A'], + "\t" => ["\t", '\\u0009'], + "\0" => ["\0", '\\u0000'], + 'Encode spaces for quoteless attribute protection' => [' ', '\\u0020'], + ]; } /** @@ -44,7 +140,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase */ public function testEscapeHtml($data, $expected, $allowedTags = []) { - $actual = $this->_escaper->escapeHtml($data, $allowedTags); + $actual = $this->escaper->escapeHtml($data, $allowedTags); $this->assertEquals($expected, $actual); } @@ -56,7 +152,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase { $this->loggerMock->expects($this->once()) ->method('critical'); - $actual = $this->_escaper->escapeHtml($data, $allowedTags); + $actual = $this->escaper->escapeHtml($data, $allowedTags); $this->assertEquals($expected, $actual); } @@ -160,8 +256,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase { $data = 'http://example.com/search?term=this+%26+that&view=list'; $expected = 'http://example.com/search?term=this+%26+that&view=list'; - $this->assertEquals($expected, $this->_escaper->escapeUrl($data)); - $this->assertEquals($expected, $this->_escaper->escapeUrl($expected)); + $this->assertEquals($expected, $this->escaper->escapeUrl($data)); + $this->assertEquals($expected, $this->escaper->escapeUrl($expected)); } /** @@ -171,8 +267,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase { $data = ["Don't do that.", 'lost_key' => "Can't do that."]; $expected = ["Don\\'t do that.", "Can\\'t do that."]; - $this->assertEquals($expected, $this->_escaper->escapeJsQuote($data)); - $this->assertEquals($expected[0], $this->_escaper->escapeJsQuote($data[0])); + $this->assertEquals($expected, $this->escaper->escapeJsQuote($data)); + $this->assertEquals($expected[0], $this->escaper->escapeJsQuote($data[0])); } /** @@ -185,8 +281,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase "Text with 'single' and "double" quotes", "Text with \\'single\\' and \\"double\\" quotes", ]; - $this->assertEquals($expected[0], $this->_escaper->escapeQuote($data)); - $this->assertEquals($expected[1], $this->_escaper->escapeQuote($data, true)); + $this->assertEquals($expected[0], $this->escaper->escapeQuote($data)); + $this->assertEquals($expected[1], $this->escaper->escapeQuote($data, true)); } /** @@ -197,7 +293,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase */ public function testEscapeXssInUrl($input, $expected) { - $this->assertEquals($expected, $this->_escaper->escapeXssInUrl($input)); + $this->assertEquals($expected, $this->escaper->escapeXssInUrl($input)); } /** -- GitLab From 5bc0ab2fd311638eee3659a764d504ed9a273cbf Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 31 Aug 2016 11:24:47 -0500 Subject: [PATCH 778/838] MAGETWO-56104: Build stablization Fixing annotation in unit test, minor refactoring --- .../Test/Unit/Block/CurrencyTest.php | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php b/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php index cfe5e2aacd3..f9921ee5425 100644 --- a/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php +++ b/app/code/Magento/Directory/Test/Unit/Block/CurrencyTest.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Directory\Test\Unit\Block; class CurrencyTest extends \PHPUnit_Framework_TestCase @@ -16,29 +15,31 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $postDataHelper; + protected $postDataHelperMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $urlBuilder; + protected $urlBuilderMock; protected function setUp() { - $this->urlBuilder = $this->getMock( + $this->urlBuilderMock = $this->getMock( \Magento\Framework\UrlInterface::class, [], [], '', false ); - $this->urlBuilder->expects($this->any())->method('getUrl')->will($this->returnArgument(0)); + $this->urlBuilderMock->expects($this->any())->method('getUrl')->will($this->returnArgument(0)); - /** @var $context \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */ - $context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class) + /** + * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject $contextMock + */ + $contextMock = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class) ->disableOriginalConstructor() ->getMock(); - $context->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilder)); + $contextMock->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilderMock)); $escaperMock = $this->getMockBuilder(\Magento\Framework\Escaper::class) ->disableOriginalConstructor() @@ -49,22 +50,22 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase return 'escapeUrl' . $string; } ); - $context->expects($this->once()) + $contextMock->expects($this->once()) ->method('getEscaper') ->willReturn($escaperMock); - /** @var \Magento\Directory\Model\CurrencyFactory $currencyFactory */ - $currencyFactory = $this->getMock(\Magento\Directory\Model\CurrencyFactory::class, [], [], '', false); - $this->postDataHelper = $this->getMock(\Magento\Framework\Data\Helper\PostHelper::class, [], [], '', false); + /** @var \Magento\Directory\Model\CurrencyFactory $currencyFactoryMock */ + $currencyFactoryMock = $this->getMock(\Magento\Directory\Model\CurrencyFactory::class, [], [], '', false); + $this->postDataHelperMock = $this->getMock(\Magento\Framework\Data\Helper\PostHelper::class, [], [], '', false); - /** @var \Magento\Framework\Locale\ResolverInterface $localeResolver */ - $localeResolver = $this->getMock(\Magento\Framework\Locale\ResolverInterface::class, [], [], '', false); + /** @var \Magento\Framework\Locale\ResolverInterface $localeResolverMock */ + $localeResolverMock = $this->getMock(\Magento\Framework\Locale\ResolverInterface::class, [], [], '', false); $this->object = new \Magento\Directory\Block\Currency( - $context, - $currencyFactory, - $this->postDataHelper, - $localeResolver + $contextMock, + $currencyFactoryMock, + $this->postDataHelperMock, + $localeResolverMock ); } @@ -74,7 +75,7 @@ class CurrencyTest extends \PHPUnit_Framework_TestCase $expectedCurrencyCode = 'test'; $switchUrl = 'escapeUrldirectory/currency/switch'; - $this->postDataHelper->expects($this->once()) + $this->postDataHelperMock->expects($this->once()) ->method('getPostData') ->with($this->equalTo($switchUrl), $this->equalTo(['currency' => $expectedCurrencyCode])) ->will($this->returnValue($expectedResult)); -- GitLab From 9dd22482598a84c2860239e16e801bf113828dae Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 31 Aug 2016 16:07:08 -0500 Subject: [PATCH 779/838] MAGETWO-57238: Build stablization Code style fixes --- .../Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php | 4 ++-- .../testsuite/Magento/Customer/Controller/AccountTest.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php index 7ddf10e58bd..5d23f6478f5 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php @@ -101,8 +101,8 @@ class CartTest extends \PHPUnit_Framework_TestCase $this->assertContains("<div class=\"admin__data-grid-header admin__data-grid-toolbar\"", $html); $this->assertContains("customer_cart_gridJsObject = new varienGrid(\"customer_cart_grid\",", $html); $this->assertContains( - 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fcustomer_id\u002F' . - self::CUSTOMER_ID_VALUE, + 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fcustomer_id\u002F' + . self::CUSTOMER_ID_VALUE, $html ); } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index d80a1ee0b10..dbe870cb03e 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -477,7 +477,8 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController // Verify the password check box is checked $this->assertContains( '<input type="checkbox" name="change_password" id="change-password" ' - .'data-role="change-password" value="1" title="Change Password" checked="checked" class="checkbox" />', + . 'data-role="change-password" value="1" title="Change Password" checked="checked" ' + . 'class="checkbox" />', $body ); } -- GitLab From 13465aa7142862055c0dcbc7f1452693bed1ddb4 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 31 Aug 2016 16:07:44 -0500 Subject: [PATCH 780/838] MAGETWO-57836: Make \Magento\Framework\Escaper::escapeJs() generate valid Json string Code style fixes --- .../Framework/Test/Unit/EscaperTest.php | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 58b45a72f1a..ac155c49945 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -39,7 +39,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase } /** - * Convert a Unicode Codepoint to a literal UTF-8 character. + * Convert a unicode codepoint to a literal UTF-8 character * * @param int $codepoint Unicode codepoint in hex notation * @return string UTF-8 literal string @@ -51,26 +51,27 @@ class EscaperTest extends \PHPUnit_Framework_TestCase } if ($codepoint < 0x800) { return chr($codepoint >> 6 & 0x3f | 0xc0) - . chr($codepoint & 0x3f | 0x80); + . chr($codepoint & 0x3f | 0x80); } if ($codepoint < 0x10000) { return chr($codepoint >> 12 & 0x0f | 0xe0) - . chr($codepoint >> 6 & 0x3f | 0x80) - . chr($codepoint & 0x3f | 0x80); + . chr($codepoint >> 6 & 0x3f | 0x80) + . chr($codepoint & 0x3f | 0x80); } if ($codepoint < 0x110000) { return chr($codepoint >> 18 & 0x07 | 0xf0) - . chr($codepoint >> 12 & 0x3f | 0x80) - . chr($codepoint >> 6 & 0x3f | 0x80) - . chr($codepoint & 0x3f | 0x80); + . chr($codepoint >> 12 & 0x3f | 0x80) + . chr($codepoint >> 6 & 0x3f | 0x80) + . chr($codepoint & 0x3f | 0x80); } - throw new \Exception('Codepoint requested outside of Unicode range'); + throw new \Exception('Codepoint requested outside of unicode range'); } public function testEscapeJsEscapesOwaspRecommendedRanges() { - $immune = [',', '.', '_']; // Exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { + // Exceptions to escaping ranges + $immune = [',', '.', '_']; + for ($chr = 0; $chr < 0xFF; $chr++) { if ($chr >= 0x30 && $chr <= 0x39 || $chr >= 0x41 && $chr <= 0x5A || $chr >= 0x61 && $chr <= 0x7A -- GitLab From 4365b1fca3fc6ccc45f03f3330be4381881fd40c Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Wed, 31 Aug 2016 18:00:17 -0500 Subject: [PATCH 781/838] MAGETWO-57238: Build stablization Code style fixes --- .../Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php | 2 +- .../testsuite/Magento/Customer/Controller/AccountTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php index 5d23f6478f5..a9e5b01fea5 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/CartTest.php @@ -102,7 +102,7 @@ class CartTest extends \PHPUnit_Framework_TestCase $this->assertContains("customer_cart_gridJsObject = new varienGrid(\"customer_cart_grid\",", $html); $this->assertContains( 'backend\u002Fcustomer\u002Fcart_product_composite_cart\u002Fconfigure\u002Fcustomer_id\u002F' - . self::CUSTOMER_ID_VALUE, + . self::CUSTOMER_ID_VALUE, $html ); } diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index dbe870cb03e..48282da9698 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -477,8 +477,8 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController // Verify the password check box is checked $this->assertContains( '<input type="checkbox" name="change_password" id="change-password" ' - . 'data-role="change-password" value="1" title="Change Password" checked="checked" ' - . 'class="checkbox" />', + . 'data-role="change-password" value="1" title="Change Password" checked="checked" ' + . 'class="checkbox" />', $body ); } -- GitLab From 159b1b9eb63a3cf6986446f7640253f8671805ef Mon Sep 17 00:00:00 2001 From: Roman Liukshyn <rliukshyn@magento.com> Date: Thu, 1 Sep 2016 10:42:11 +0300 Subject: [PATCH 782/838] MAGETWO-57228: Update BIN ranges for Discover Network and Mastercard for server validation - Fixed excessive line length --- app/code/Magento/Payment/Model/Method/Cc.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Payment/Model/Method/Cc.php b/app/code/Magento/Payment/Model/Method/Cc.php index 327dd1dee51..f5dd670b2ed 100644 --- a/app/code/Magento/Payment/Model/Method/Cc.php +++ b/app/code/Magento/Payment/Model/Method/Cc.php @@ -127,10 +127,10 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod //Solo, Switch or Maestro. International safe 'SO' => '/(^(6334)[5-9](\d{11}$|\d{13,14}$))|(^(6767)(\d{12}$|\d{14,15}$))/', 'SM' => '/(^(5[0678])\d{11,18}$)|(^(6[^05])\d{11,18}$)|(^(601)[^1]\d{9,16}$)|(^(6011)\d{9,11}$)' . - '|(^(6011)\d{13,16}$)|(^(65)\d{11,13}$)|(^(65)\d{15,18}$)' . - '|(^(49030)[2-9](\d{10}$|\d{12,13}$))|(^(49033)[5-9](\d{10}$|\d{12,13}$))' . - '|(^(49110)[1-2](\d{10}$|\d{12,13}$))|(^(49117)[4-9](\d{10}$|\d{12,13}$))' . - '|(^(49118)[0-2](\d{10}$|\d{12,13}$))|(^(4936)(\d{12}$|\d{14,15}$))/', + '|(^(6011)\d{13,16}$)|(^(65)\d{11,13}$)|(^(65)\d{15,18}$)' . + '|(^(49030)[2-9](\d{10}$|\d{12,13}$))|(^(49033)[5-9](\d{10}$|\d{12,13}$))' . + '|(^(49110)[1-2](\d{10}$|\d{12,13}$))|(^(49117)[4-9](\d{10}$|\d{12,13}$))' . + '|(^(49118)[0-2](\d{10}$|\d{12,13}$))|(^(4936)(\d{12}$|\d{14,15}$))/', // Visa 'VI' => '/^4[0-9]{12}([0-9]{3})?$/', // Master Card @@ -138,10 +138,12 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod // American Express 'AE' => '/^3[47][0-9]{13}$/', // Discover - 'DI' => '/^(6011((0|9|[2-4])[0-9]{11,14}|(74|7[7-9]|8[6-9])[0-9]{10,13})|6(4[4-9][0-9]{13,16}|5[0-9]{14,17}))/', + 'DI' => '/^(6011((0|9|[2-4])[0-9]{11,14}|(74|7[7-9]|8[6-9])[0-9]{10,13})|6(4[4-9][0-9]{13,16}|' . + '5[0-9]{14,17}))/', 'DN' => '/^3(0[0-5][0-9]{13,16}|095[0-9]{12,15}|(6|[8-9])[0-9]{14,17})/', // UnionPay - 'UN' => '/^622(1(2[6-9][0-9]{10,13}|[3-9][0-9]{11,14})|[3-8][0-9]{12,15}|9([[0-1][0-9]{11,14}|2[0-5][0-9]{10,13}))|62[4-6][0-9]{13,16}|628[2-8][0-9]{12,15}/', + 'UN' => '/^622(1(2[6-9][0-9]{10,13}|[3-9][0-9]{11,14})|[3-8][0-9]{12,15}|9([[0-1][0-9]{11,14}|' . + '2[0-5][0-9]{10,13}))|62[4-6][0-9]{13,16}|628[2-8][0-9]{12,15}/', // JCB 'JCB' => '/^35(2[8-9][0-9]{12,15}|[3-8][0-9]{13,16})/', 'MI' => '/^(5(0|[6-9])|63|67(?!59|6770|6774))\d*$/', -- GitLab From fc20d3e5a12105d03479b42d6f42c0f0632efac8 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Thu, 1 Sep 2016 11:11:36 +0300 Subject: [PATCH 783/838] MAGETWO-57726: [GitHub] Exception is created but not thrown #6320 - Added unit and integration tests --- .../Test/Unit/Block/Product/ComparedTest.php | 66 ++++++++++++++++++ .../Product/Lowstock/CollectionTest.php | 68 +++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php diff --git a/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php b/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php new file mode 100644 index 00000000000..e8913e4adb3 --- /dev/null +++ b/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Reports\Test\Unit\Block\Product; + +use \Magento\Reports\Block\Product\Compared; +use \Magento\Reports\Model\Product\Index\Factory; + +class ComparedTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \Magento\Reports\Block\Product\Compared; + */ + private $sut; + + /** + * @var Factory|\PHPUnit_Framework_MockObject_MockObject + */ + private $factoryMock; + + protected function setUp() + { + $contextMock = $this->getMockBuilder(\Magento\Catalog\Block\Product\Context::class) + ->disableOriginalConstructor() + ->getMock(); + $visibilityMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Visibility::class) + ->disableOriginalConstructor() + ->getMock(); + $this->factoryMock = $this->getMockBuilder(\Magento\Reports\Model\Product\Index\Factory::class) + ->disableOriginalConstructor() + ->setMethods(['get']) + ->getMock(); + + $this->sut = new Compared($contextMock, $visibilityMock, $this->factoryMock); + } + + /** + * Assert that getModel method throws LocalizedException + * + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testGetModelException() + { + $this->factoryMock->expects($this->once())->method('get')->willThrowException(new \InvalidArgumentException); + + $this->sut->getModel(); + } + + /** + * Assert that getModel method returns AbstractIndex + */ + public function testGetModel() + { + $indexMock = $this->getMockBuilder(\Magento\Reports\Model\Product\Index\AbstractIndex::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->factoryMock->expects($this->once())->method('get')->willReturn($indexMock); + + $this->assertSame($indexMock, $this->sut->getModel()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php new file mode 100644 index 00000000000..aa8d6c2bd65 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection; + + +class CollectionTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection + */ + private $collection; + + protected function setUp() + { + /** + * @var \Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection + */ + $this->collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection::class + ); + } + + /** + * Assert that filterByProductType method throws LocalizedException if not String or Array is passed to it + * + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testFilterByProductTypeException() + { + $this->collection->filterByProductType(100); + } + + /** + * Assert that String argument passed to filterByProductType method is correctly passed to attribute adder + * + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testFilterByProductTypeString() + { + $this->collection->filterByProductType('simple'); + $whereParts = $this->collection->getSelect()->getPart(\Zend_Db_Select::WHERE); + $this->assertContains('simple', $whereParts[0]); + } + + /** + * Assert that Array argument passed to filterByProductType method is correctly passed to attribute adder + * + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testFilterByProductTypeArray() + { + $this->collection->filterByProductType(['simple', 'configurable']); + $whereParts = $this->collection->getSelect()->getPart(\Zend_Db_Select::WHERE); + + $this->assertThat( + $whereParts[0], + $this->logicalAnd( + $this->stringContains('simple'), + $this->stringContains('configurable') + ) + ); + } +} -- GitLab From 7e91889b385fb70f166bb39aaa39f23c5c0797b1 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Thu, 1 Sep 2016 11:10:23 +0300 Subject: [PATCH 784/838] MAGETWO-56541: Integration test coverage --- .../Magento/Catalog/_files/product_simple.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index aadf1e74a88..17f08af02aa 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -45,8 +45,6 @@ $tierPrices[] = $tierPriceFactory->create( ] ); /** @var $tpExtensionAttributes */ -$tpExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); -$tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); $tierPrices[] = $tierPriceFactory->create( [ @@ -55,7 +53,7 @@ $tierPrices[] = $tierPriceFactory->create( 'qty' => 10 ] ] -)->setExtensionAttributes($tpExtensionAttributes); +); $tierPrices = []; /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory */ @@ -87,10 +85,6 @@ $tierPrices[] = $tierPriceFactory->create( ] ] ); -/** @var $tpExtensionAttributes */ -$tpExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); -$tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); - $tierPrices[] = $tierPriceFactory->create( [ 'data' => [ @@ -98,7 +92,7 @@ $tierPrices[] = $tierPriceFactory->create( 'qty' => 10 ] ] -)->setExtensionAttributes($tpExtensionAttributes); +); /** @var $product \Magento\Catalog\Model\Product */ $product = $objectManager->create(\Magento\Catalog\Model\Product::class); -- GitLab From a9ba538e499547ed8b9eddbc15c1a45bf108c560 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Thu, 1 Sep 2016 12:10:26 +0300 Subject: [PATCH 785/838] MAGETWO-56541: Integration test coverage --- .../Magento/Catalog/_files/product_simple.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php index 17f08af02aa..aadf1e74a88 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php @@ -45,6 +45,8 @@ $tierPrices[] = $tierPriceFactory->create( ] ); /** @var $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); +$tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); $tierPrices[] = $tierPriceFactory->create( [ @@ -53,7 +55,7 @@ $tierPrices[] = $tierPriceFactory->create( 'qty' => 10 ] ] -); +)->setExtensionAttributes($tpExtensionAttributes); $tierPrices = []; /** @var \Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory $tierPriceFactory */ @@ -85,6 +87,10 @@ $tierPrices[] = $tierPriceFactory->create( ] ] ); +/** @var $tpExtensionAttributes */ +$tpExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); +$tpExtensionAttributes = $tpExtensionAttributesFactory->create()->setPercentageValue(50); + $tierPrices[] = $tierPriceFactory->create( [ 'data' => [ @@ -92,7 +98,7 @@ $tierPrices[] = $tierPriceFactory->create( 'qty' => 10 ] ] -); +)->setExtensionAttributes($tpExtensionAttributes); /** @var $product \Magento\Catalog\Model\Product */ $product = $objectManager->create(\Magento\Catalog\Model\Product::class); -- GitLab From 004b0b29939759061aaadf42f84f23aa77c64292 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Wed, 31 Aug 2016 13:00:07 +0300 Subject: [PATCH 786/838] MAGETWO-57805: [mainline] It is possible to delete self admin account or role --- app/code/Magento/User/Block/User/Edit.php | 16 +++++++++- .../User/Controller/Adminhtml/User/Delete.php | 2 +- .../Controller/Adminhtml/User/DeleteTest.php | 31 +++++++++++++++++++ lib/web/mage/adminhtml/globals.js | 15 ++++++--- 4 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/DeleteTest.php diff --git a/app/code/Magento/User/Block/User/Edit.php b/app/code/Magento/User/Block/User/Edit.php index bd69d23b01a..f6c5b484861 100644 --- a/app/code/Magento/User/Block/User/Edit.php +++ b/app/code/Magento/User/Block/User/Edit.php @@ -48,11 +48,25 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container parent::_construct(); $this->buttonList->update('save', 'label', __('Save User')); - $this->buttonList->update('delete', 'label', __('Delete User')); + $this->buttonList->remove('delete'); $objId = $this->getRequest()->getParam($this->_objectId); if (!empty($objId)) { + $this->addButton( + 'delete', + [ + 'label' => __('Delete User'), + 'class' => 'delete', + 'onclick' => sprintf( + 'deleteConfirm("%s", "%s", %s)', + __('Are you sure you want to do this?'), + $this->getUrl('adminhtml/*/delete'), + json_encode(['data' => ['user_id' => $objId]]) + ), + ] + ); + $deleteConfirmMsg = __("Are you sure you want to revoke the user\'s tokens?"); $this->addButton( 'invalidate', diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Delete.php b/app/code/Magento/User/Controller/Adminhtml/User/Delete.php index 81e09ec98a3..570cf4132c6 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Delete.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Delete.php @@ -15,7 +15,7 @@ class Delete extends \Magento\User\Controller\Adminhtml\User { $currentUser = $this->_objectManager->get(\Magento\Backend\Model\Auth\Session::class)->getUser(); - if ($userId = $this->getRequest()->getParam('user_id')) { + if ($userId = (int)$this->getRequest()->getPost('user_id')) { if ($currentUser->getId() == $userId) { $this->messageManager->addError(__('You cannot delete your own account.')); $this->_redirect('adminhtml/*/edit', ['user_id' => $userId]); diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/DeleteTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/DeleteTest.php new file mode 100644 index 00000000000..bf43fd9f29c --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/User/DeleteTest.php @@ -0,0 +1,31 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\User\Controller\Adminhtml\User; + +/** + * Test class for \Magento\User\Controller\Adminhtml\User\Delete + * @magentoAppArea adminhtml + */ +class DeleteTest extends \Magento\TestFramework\TestCase\AbstractBackendController +{ + /** + * @covers \Magento\User\Controller\Adminhtml\User\Delete::execute + */ + public function testDeleteActionWithError() + { + $user = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\User\Model\User::class); + /** @var \Magento\Framework\Message\ManagerInterface $messageManager */ + $messageManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Message\ManagerInterface::class); + $user->load(1); + $this->getRequest()->setPostValue('user_id', $user->getId() . '_suffix_ignored_in_mysql_casting_to_int'); + + $this->dispatch('backend/admin/user/delete'); + $message = $messageManager->getMessages()->getLastAddedMessage()->getText(); + $this->assertEquals('You cannot delete your own account.', $message); + } +} diff --git a/lib/web/mage/adminhtml/globals.js b/lib/web/mage/adminhtml/globals.js index ad9e500132c..e94b1cce489 100644 --- a/lib/web/mage/adminhtml/globals.js +++ b/lib/web/mage/adminhtml/globals.js @@ -3,8 +3,9 @@ * See COPYING.txt for license details. */ define([ - 'Magento_Ui/js/modal/confirm' -], function (confirm) { + 'Magento_Ui/js/modal/confirm', + 'mage/dataPost' +], function (confirm, dataPost) { 'use strict'; /** @@ -19,14 +20,20 @@ define([ * Helper for onclick action. * @param {String} message * @param {String} url + * @param {Object} postData * @returns {boolean} */ - window.deleteConfirm = function (message, url) { + window.deleteConfirm = function (message, url, postData) { confirm({ content: message, actions: { confirm: function () { - setLocation(url); + if (postData !== undefined) { + postData.action = url; + dataPost().postData(postData); + } else { + setLocation(url); + } } } }); -- GitLab From 2e5baa12aff6603efe1f9d5b9e15d067ee42b5cd Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Thu, 1 Sep 2016 12:31:57 +0300 Subject: [PATCH 787/838] MAGETWO-57726: [GitHub] Exception is created but not thrown #6320 - Refactor --- .../Reports/Test/Unit/Block/Product/ComparedTest.php | 8 +++++--- .../ResourceModel/Product/Lowstock/CollectionTest.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php b/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php index e8913e4adb3..f7030b8a731 100644 --- a/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php +++ b/app/code/Magento/Reports/Test/Unit/Block/Product/ComparedTest.php @@ -27,10 +27,12 @@ class ComparedTest extends \PHPUnit_Framework_TestCase $contextMock = $this->getMockBuilder(\Magento\Catalog\Block\Product\Context::class) ->disableOriginalConstructor() ->getMock(); + $visibilityMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Visibility::class) ->disableOriginalConstructor() ->getMock(); - $this->factoryMock = $this->getMockBuilder(\Magento\Reports\Model\Product\Index\Factory::class) + + $this->factoryMock = $this->getMockBuilder(Factory::class) ->disableOriginalConstructor() ->setMethods(['get']) ->getMock(); @@ -56,8 +58,8 @@ class ComparedTest extends \PHPUnit_Framework_TestCase public function testGetModel() { $indexMock = $this->getMockBuilder(\Magento\Reports\Model\Product\Index\AbstractIndex::class) - ->disableOriginalConstructor() - ->getMock(); + ->disableOriginalConstructor() + ->getMock(); $this->factoryMock->expects($this->once())->method('get')->willReturn($indexMock); diff --git a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php index aa8d6c2bd65..65a0512b9cf 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php @@ -43,7 +43,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase public function testFilterByProductTypeString() { $this->collection->filterByProductType('simple'); - $whereParts = $this->collection->getSelect()->getPart(\Zend_Db_Select::WHERE); + $whereParts = $this->collection->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE); $this->assertContains('simple', $whereParts[0]); } @@ -55,7 +55,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase public function testFilterByProductTypeArray() { $this->collection->filterByProductType(['simple', 'configurable']); - $whereParts = $this->collection->getSelect()->getPart(\Zend_Db_Select::WHERE); + $whereParts = $this->collection->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE); $this->assertThat( $whereParts[0], -- GitLab From 9367990e5cf5f59cb376193e56f3707846acf6ba Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Thu, 1 Sep 2016 13:46:41 +0300 Subject: [PATCH 788/838] MAGETWO-57726: [GitHub] Exception is created but not thrown #6320 - Fixed namespace --- .../Model/ResourceModel/Product/Lowstock/CollectionTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php index 65a0512b9cf..a44f3a3d9eb 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php @@ -4,8 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection; - +namespace \Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection; class CollectionTest extends \PHPUnit_Framework_TestCase { -- GitLab From 8af37f7078852d84bc55665d7ae5970e4faa9c3f Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Thu, 1 Sep 2016 13:59:06 +0300 Subject: [PATCH 789/838] MAGETWO-57726: [GitHub] Exception is created but not thrown #6320 --- .../Model/ResourceModel/Product/Lowstock/CollectionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php index a44f3a3d9eb..bd1f460db83 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace \Magento\Reports\Model\ResourceModel\Product\Lowstock\Collection; +namespace \Magento\Reports\Model\ResourceModel\Product\Lowstock; class CollectionTest extends \PHPUnit_Framework_TestCase { -- GitLab From 22d988716bf9f0b8bcc66f24d3260eec55a826a9 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Thu, 1 Sep 2016 15:58:16 +0300 Subject: [PATCH 790/838] MAGETWO-57726: [GitHub] Exception is created but not thrown #6320 --- .../Model/ResourceModel/Product/Lowstock/CollectionTest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php index bd1f460db83..ab453be8322 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php @@ -3,9 +3,11 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ +namespace Magento\Reports\Model\ResourceModel\Product\Lowstock; -namespace \Magento\Reports\Model\ResourceModel\Product\Lowstock; - +/** + * Class CollectionTest + */ class CollectionTest extends \PHPUnit_Framework_TestCase { -- GitLab From d66748032936d4f48c937343a9906fea8acdd132 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Thu, 1 Sep 2016 16:25:36 +0300 Subject: [PATCH 791/838] MAGETWO-55433: [Github # 6294] Coupon code override cart rules with no coupon code --- .../Model/ResourceModel/Rule/Collection.php | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php index cbc7b4385ec..626e1e0aa93 100644 --- a/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php +++ b/app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php @@ -4,8 +4,6 @@ * See COPYING.txt for license details. */ -// @codingStandardsIgnoreFile - namespace Magento\SalesRule\Model\ResourceModel\Rule; use Magento\Quote\Model\Quote\Address; @@ -153,11 +151,12 @@ class Collection extends \Magento\Rule\Model\ResourceModel\Rule\Collection\Abstr ['code'] ); + $noCouponWhereCondition = $connection->quoteInto( + 'main_table.coupon_type = ? ', + \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON + ); + $orWhereConditions = [ - $connection->quoteInto( - 'main_table.coupon_type = ? ', - \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON - ), $connection->quoteInto( '(main_table.coupon_type = ? AND rule_coupons.type = 0)', \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO @@ -186,7 +185,9 @@ class Collection extends \Magento\Rule\Model\ResourceModel\Rule\Collection\Abstr $orWhereCondition = implode(' OR ', $orWhereConditions); $andWhereCondition = implode(' AND ', $andWhereConditions); - $select->where('(' . $orWhereCondition . ') AND ' . $andWhereCondition); + $select->where( + $noCouponWhereCondition . ' OR ((' . $orWhereCondition . ') AND ' . $andWhereCondition . ')' + ); } else { $this->addFieldToFilter( 'main_table.coupon_type', @@ -214,7 +215,7 @@ class Collection extends \Magento\Rule\Model\ResourceModel\Rule\Collection\Abstr public function addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now = null) { if (!$this->getFlag('website_group_date_filter')) { - if (is_null($now)) { + if ($now === null) { $now = $this->_date->date()->format('Y-m-d'); } @@ -277,7 +278,11 @@ class Collection extends \Magento\Rule\Model\ResourceModel\Rule\Collection\Abstr $field = $this->_getMappedField('actions_serialized'); $aCond = $this->_getConditionSql($field, ['like' => $match]); - $this->getSelect()->where(sprintf('(%s OR %s)', $cCond, $aCond), null, \Magento\Framework\DB\Select::TYPE_CONDITION); + $this->getSelect()->where( + sprintf('(%s OR %s)', $cCond, $aCond), + null, + \Magento\Framework\DB\Select::TYPE_CONDITION + ); return $this; } -- GitLab From 46bdd7eb080a25929b64d4626bd4d545ff27a91c Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 1 Sep 2016 16:31:20 +0300 Subject: [PATCH 792/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- .../Console/Command/ImagesResizeCommand.php | 3 ++ lib/internal/Magento/Framework/App/Area.php | 21 -------------- lib/internal/Magento/Framework/App/State.php | 28 +++++++++++++++++-- .../Framework/App/Test/Unit/AreaTest.php | 6 ---- .../Framework/App/Test/Unit/StateTest.php | 21 +++++++++++++- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php b/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php index abfdc4bdb75..3a3c80f9987 100644 --- a/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php +++ b/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php @@ -16,6 +16,9 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class ImagesResizeCommand extends Command { /** diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php index 013e2fa6a88..20dbbe01d9f 100644 --- a/lib/internal/Magento/Framework/App/Area.php +++ b/lib/internal/Magento/Framework/App/Area.php @@ -29,16 +29,6 @@ class Area implements \Magento\Framework\App\AreaInterface */ const PARAM_AREA = 'area'; - /** - * List of existing areas - * - * @var array - */ - private static $existingAreas = [ - self::AREA_GLOBAL, self::AREA_FRONTEND, self::AREA_ADMIN, self::AREA_ADMINHTML, - self::AREA_DOC, self::AREA_CRONTAB, self::AREA_WEBAPI_REST, self::AREA_WEBAPI_SOAP - ]; - /** * Array of area loaded parts * @@ -170,17 +160,6 @@ class Area implements \Magento\Framework\App\AreaInterface } } - /** - * Check that area exists - * - * @param string $areaCode - * @return bool - */ - public static function doesAreaExist($areaCode) - { - return in_array($areaCode, self::$existingAreas); - } - /** * Analyze user-agent information to override custom design settings * diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index 47ad2350a4d..de4b21b70da 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -7,8 +7,6 @@ */ namespace Magento\Framework\App; -use Magento\Framework\App\Area; - class State { /** @@ -58,6 +56,11 @@ class State */ protected $_isAreaCodeEmulated = false; + /** + * @var AreaList + */ + private $areaList; + /**#@+ * Application modes */ @@ -194,10 +197,29 @@ class State */ private function checkAreaCode($areaCode) { - if (!Area::doesAreaExist($areaCode)) { + $areaCodes = array_merge( + [Area::AREA_GLOBAL, Area::AREA_ADMIN], + $this->getAreaListInstance()->getCodes() + ); + + if (!in_array($areaCode, $areaCodes)) { throw new \Magento\Framework\Exception\LocalizedException( new \Magento\Framework\Phrase('Area code "%1" does not exist', [$areaCode]) ); } } + + /** + * Get Instance of AreaList + * + * @return AreaList + */ + private function getAreaListInstance() + { + if ($this->areaList === null) { + $this->areaList = ObjectManager::getInstance()->get(AreaList::class); + } + + return $this->areaList; + } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php b/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php index 2416ba6f9b8..a280658ca2a 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/AreaTest.php @@ -315,10 +315,4 @@ class AreaTest extends \PHPUnit_Framework_TestCase ->with($exception); $this->object->detectDesign($requestMock); } - - public function testDoesAreaExist() - { - $this->assertTrue($this->object->doesAreaExist(Area::AREA_FRONTEND)); - $this->assertFalse($this->object->doesAreaExist('any area')); - } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php b/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php index c10f7d66d3d..ae3845834ee 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/StateTest.php @@ -9,6 +9,8 @@ namespace Magento\Framework\App\Test\Unit; use \Magento\Framework\App\Area; +use \Magento\Framework\App\AreaList; +use \Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; class StateTest extends \PHPUnit_Framework_TestCase { @@ -22,15 +24,32 @@ class StateTest extends \PHPUnit_Framework_TestCase */ protected $scopeMock; + /** + * @var AreaList|\PHPUnit_Framework_MockObject_MockObject + */ + protected $areaListMock; + protected function setUp() { + $objectManager = new ObjectManagerHelper($this); $this->scopeMock = $this->getMockForAbstractClass( \Magento\Framework\Config\ScopeInterface::class, ['setCurrentScope'], '', false ); - $this->model = new \Magento\Framework\App\State($this->scopeMock); + + $this->areaListMock = $this->getMock(AreaList::class, [], [], '', false, false); + $this->areaListMock->expects($this->any()) + ->method('getCodes') + ->willReturn([Area::AREA_ADMINHTML, Area::AREA_FRONTEND]); + + $this->model = $objectManager->getObject( + \Magento\Framework\App\State::class, + ['configScope' => $this->scopeMock] + ); + + $objectManager->setBackwardCompatibleProperty($this->model, 'areaList', $this->areaListMock); } public function testSetAreaCode() -- GitLab From 10299bc2aed2bc23f6fb589633dc5821daad5792 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Thu, 1 Sep 2016 16:48:07 +0300 Subject: [PATCH 793/838] MAGETWO-57726: [GitHub] Exception is created but not thrown #6320 --- .../Model/ResourceModel/Product/Lowstock/CollectionTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php index ab453be8322..bdd0dfac712 100644 --- a/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Reports/Model/ResourceModel/Product/Lowstock/CollectionTest.php @@ -39,7 +39,6 @@ class CollectionTest extends \PHPUnit_Framework_TestCase /** * Assert that String argument passed to filterByProductType method is correctly passed to attribute adder * - * @expectedException \Magento\Framework\Exception\LocalizedException */ public function testFilterByProductTypeString() { @@ -51,7 +50,6 @@ class CollectionTest extends \PHPUnit_Framework_TestCase /** * Assert that Array argument passed to filterByProductType method is correctly passed to attribute adder * - * @expectedException \Magento\Framework\Exception\LocalizedException */ public function testFilterByProductTypeArray() { -- GitLab From 1c45680f0834e255af958ba1f24886e91d085488 Mon Sep 17 00:00:00 2001 From: sdwright <swright@magento.com> Date: Mon, 29 Aug 2016 15:23:54 -0500 Subject: [PATCH 794/838] MAGETWO-55506: [PAT test investigation] - JMeter log clean up - Removed logging of category. --- setup/performance-toolkit/benchmark.jmx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 4f212b4c3d9..c2ef9ebbea0 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -790,7 +790,7 @@ if (1 == Integer.parseInt(vars.get("category_name_counter"))) { } else { categoryNamesList = props.get("category_names_list"); } -log.info("category name: " + vars.get("category_name")); + categoryNamesList.add(vars.get("category_name"));</stringProp> <stringProp name="BeanShellSampler.filename"/> <stringProp name="BeanShellSampler.parameters"/> -- GitLab From 25e0aa85fa02ce7f02444d7cfc051c538526bf5a Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 1 Sep 2016 17:47:00 +0300 Subject: [PATCH 795/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- .../Test/Unit/Block/Adminhtml/Template/PreviewTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 5d290b66365..fd52d57ff93 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -84,9 +84,13 @@ class PreviewTest extends \PHPUnit_Framework_TestCase ->setConstructorArgs([ $scopeConfig ]) - ->setMethods(null) + ->setMethods(['emulateAreaCode']) ->disableOriginalConstructor() ->getMock(); + $appState->expects($this->any()) + ->method('emulateAreaCode') + ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$template, 'getProcessedTemplate']) + ->willReturn($template->getProcessedTemplate()); $context = $this->getMock( \Magento\Backend\Block\Template\Context::class, -- GitLab From 0693ee8a3002f8a3e0ac180e1c1049a10b523950 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 1 Sep 2016 17:54:55 +0300 Subject: [PATCH 796/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- lib/internal/Magento/Framework/App/State.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index de4b21b70da..0a759deb447 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -198,7 +198,7 @@ class State private function checkAreaCode($areaCode) { $areaCodes = array_merge( - [Area::AREA_GLOBAL, Area::AREA_ADMIN], + [Area::AREA_GLOBAL, Area::AREA_ADMIN, Area::AREA_FRONTEND, Area::AREA_ADMINHTML], $this->getAreaListInstance()->getCodes() ); -- GitLab From c34974d3897774693d8f2cafe1727f7c5deffe73 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Thu, 1 Sep 2016 18:05:47 +0300 Subject: [PATCH 797/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- .../Magento/Setup/Test/Unit/Model/InstallerTest.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php index c40ef99d4e9..01fc9a32511 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php @@ -270,9 +270,13 @@ class InstallerTest extends \PHPUnit_Framework_TestCase $cacheManager->expects($this->any())->method('getAvailableTypes')->willReturn(['foo', 'bar']); $cacheManager->expects($this->once())->method('setEnabled')->willReturn(['foo', 'bar']); $cacheManager->expects($this->any())->method('clean'); - $appState = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( - \Magento\Framework\App\State::class - ); + $appState = $this->getMockBuilder(\Magento\Framework\App\State::class) + ->disableOriginalConstructor() + ->disableArgumentCloning() + ->getMock(); + $appState->expects($this->once()) + ->method('setAreaCode') + ->with(\Magento\Framework\App\Area::AREA_GLOBAL); $this->setupFactory->expects($this->atLeastOnce())->method('create')->with($resource)->willReturn($setup); $this->dataSetupFactory->expects($this->atLeastOnce())->method('create')->willReturn($dataSetup); $this->objectManager->expects($this->any()) -- GitLab From df261e75bd8ef839139da78f3c0d8bb14a0747b4 Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Thu, 1 Sep 2016 17:13:48 -0500 Subject: [PATCH 798/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 2 +- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 16d7c57a083..f979ed5e5a8 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -76,7 +76,7 @@ class Escaper } catch (\Exception $e) { restore_error_handler(); $this->getLogger()->critical($e); - return ''; + return $this->escapeHtml($data); } restore_error_handler(); diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index ac155c49945..32875903908 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -225,7 +225,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase ], 'html and body tags' => [ 'data' => '<html><body><span>String</span></body></html>', - 'expected' => '', + 'expected' => '<html><body><span>String</span></body></html>', 'allowedTags' => ['span'], ], ]; @@ -244,7 +244,7 @@ class EscaperTest extends \PHPUnit_Framework_TestCase ], 'text with invalid html' => [ 'data' => '<spa>n id="id1">Some string</span>', - 'expected' => '', + 'expected' => '<spa>n id="id1">Some string</span>', 'allowedTags' => ['span'], ], ]; -- GitLab From 112713001f49a4b75b7e9df4b836abfdf84944fd Mon Sep 17 00:00:00 2001 From: Hayder Sharhan <hsharhan@magento.com> Date: Thu, 1 Sep 2016 17:20:27 -0500 Subject: [PATCH 799/838] MAGETWO-55871: Eliminate @escapeNotVerified in Email module - Fixed formatting. --- .../view/adminhtml/templates/session/activity.phtml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml index d29147ae7f4..37d4b0540a0 100644 --- a/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml +++ b/app/code/Magento/Security/view/adminhtml/templates/session/activity.phtml @@ -55,9 +55,11 @@ $sessionInfoCollection = $block->getSessionInfoCollection(); if ($block->areMultipleSessionsActive()): ?> data-mage-init='{"confirmRedirect":{ "message": "<?php - echo $block->escapeJs(__('Are you sure that you want to log out all other sessions?')) ?>", + echo $block->escapeJs(__('Are you sure that you want to log out all other sessions?')) + ?>", "url":"<?php - echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/logoutAll'))) ?>" + echo $block->escapeJs($block->escapeUrl($block->getUrl('security/session/logoutAll'))) + ?>" }}' <?php else: ?>disabled<?php -- GitLab From cd813e446273d5f1cb365fa7e0abce82b81f6833 Mon Sep 17 00:00:00 2001 From: Olga Nakonechna <onakonechna@magento.com> Date: Fri, 2 Sep 2016 12:29:34 +0300 Subject: [PATCH 800/838] MAGETWO-52974: CLONE - Configurable product options not saved when editing --- .../web/js/configurable-customer-data.js | 65 +++------------- .../view/frontend/web/js/options-updater.js | 77 +++++++++++++++++++ .../web/js/configurable-customer-data.js | 67 +++------------- 3 files changed, 100 insertions(+), 109 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js index b98f7520549..7316f7b75e8 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable-customer-data.js @@ -1,71 +1,28 @@ require([ 'jquery', - 'Magento_Customer/js/customer-data' -], function ($, customerData) { + 'Magento_ConfigurableProduct/js/options-updater' +], function ($, Updater) { 'use strict'; var selectors = { - configurableWidget: 'mageConfigurable', - formSelector: '#product_addtocart_form', - productIdSelector: '#product_addtocart_form [name="product"]' - }, - configurableWidget, - productOptions, - changedProductOptions, - cartData = customerData.get('cart'), - productId = $(selectors.productIdSelector).val(), - updateConfigurableOptions, - setProductOptions; + formSelector: '#product_addtocart_form' + }, + configurableWidgetName = 'mageConfigurable', + widgetInitEvent = 'configurable.initialized', /** * Sets all configurable attribute's selected values */ updateConfigurableOptions = function () { - configurableWidget = $(selectors.formSelector).data(selectors.configurableWidget); + var configurableWidget = $(selectors.formSelector).data(configurableWidgetName); if (!configurableWidget) { return; } - configurableWidget.options.values = productOptions || {}; + configurableWidget.options.values = this.productOptions || {}; configurableWidget._configureForValues(); - }; - - /** - * set productOptions according to cart data from customer-data - * - * @param {Object} data - cart data from customer-data - * @returns {Boolean} - whether the new options differ from previous - */ - setProductOptions = function (data) { - if (!(data && data.items && data.items.length && productId)) { - return false; - } - changedProductOptions = data.items.find(function (item) { - return item['product_id'] === productId; - }); - changedProductOptions = changedProductOptions && changedProductOptions.options && - changedProductOptions.options.reduce(function (obj, val) { - obj[val['option_id']] = val['option_value']; - - return obj; - }, {}); - - if (JSON.stringify(productOptions || {}) === JSON.stringify(changedProductOptions || {})) { - return false; - } - - productOptions = changedProductOptions; - - return true; - }; + }, + updater = new Updater(widgetInitEvent, updateConfigurableOptions); - cartData.subscribe(function (updateCartData) { - if (setProductOptions(updateCartData)) { - updateConfigurableOptions(); - } - }); - $(selectors.formSelector).on('configurable.initialized', function () { - setProductOptions(cartData()); - updateConfigurableOptions(); - }); + updater.listen(); }); diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js new file mode 100644 index 00000000000..64aefc27dc0 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/options-updater.js @@ -0,0 +1,77 @@ +define([ + 'jquery', + 'Magento_Customer/js/customer-data' +], function ($, customerData) { + 'use strict'; + + var selectors = { + formSelector: '#product_addtocart_form', + productIdSelector: '#product_addtocart_form [name="product"]' + }, + cartData = customerData.get('cart'), + productId = $(selectors.productIdSelector).val(), + + /** + * set productOptions according to cart data from customer-data + * + * @param {Object} data - cart data from customer-data + * @returns {Boolean} - whether the new options differ from previous + */ + setProductOptions = function (data) { + var changedProductOptions; + + if (!(data && data.items && data.items.length && productId)) { + return false; + } + changedProductOptions = data.items.find(function (item) { + return item['product_id'] === productId; + }); + changedProductOptions = changedProductOptions && changedProductOptions.options && + changedProductOptions.options.reduce(function (obj, val) { + obj[val['option_id']] = val['option_value']; + + return obj; + }, {}); + + if (JSON.stringify(this.productOptions || {}) === JSON.stringify(changedProductOptions || {})) { + return false; + } + + this.productOptions = changedProductOptions; + + return true; + }, + + /** + * Listens to update of cart data or options initialization and update selected option according to customer data + * + */ + listen = function () { + cartData.subscribe(function (updateCartData) { + if (this.setProductOptions(updateCartData)) { + this.updateOptions(); + } + }.bind(this)); + $(selectors.formSelector).on(this.eventName, function () { + this.setProductOptions(cartData()); + this.updateOptions(); + }.bind(this)); + }, + + /** + * Updater constructor function + * + */ + Updater = function (eventName, updateOptionsCallback) { + if (this instanceof Updater) { + this.eventName = eventName; + this.updateOptions = updateOptionsCallback; + this.productOptions = {}; + } + }; + + Updater.prototype.setProductOptions = setProductOptions; + Updater.prototype.listen = listen; + + return Updater; +}); diff --git a/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js b/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js index cea3d6312d3..6467c6276da 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/configurable-customer-data.js @@ -1,71 +1,28 @@ require([ 'jquery', - 'Magento_Customer/js/customer-data' -], function ($, customerData) { + 'Magento_ConfigurableProduct/js/options-updater' +], function ($, Updater) { 'use strict'; var selectors = { - swatchWidget: 'mageSwatchRenderer', - formSelector: '#product_addtocart_form', - swatchSelector: '.swatch-opt', - productIdSelector: '#product_addtocart_form [name="product"]' - }, - swatchWidget, - productOptions, - changedProductOptions, - cartData = customerData.get('cart'), - productId = $(selectors.productIdSelector).val(), - updateSwatchOptions, - setProductOptions; + formSelector: '#product_addtocart_form', + swatchSelector: '.swatch-opt' + }, + swatchWidgetName = 'mageSwatchRenderer', + widgetInitEvent = 'swatch.initialized', /** * Sets all configurable swatch attribute's selected values */ updateSwatchOptions = function () { - swatchWidget = $(selectors.swatchSelector).data(selectors.swatchWidget); + var swatchWidget = $(selectors.swatchSelector).data(swatchWidgetName); if (!swatchWidget || !swatchWidget._EmulateSelectedByAttributeId) { return; } - swatchWidget._EmulateSelectedByAttributeId(productOptions); - }; - - /** - * set productOptions according to cart data from customer-data - * - * @param {Object} data - cart data from customer-data - * @returns {Boolean} - whether the new options differ from previous - */ - setProductOptions = function (data) { - if (!(data && data.items && data.items.length && productId)) { - return false; - } - changedProductOptions = data.items.find(function (item) { - return item['product_id'] === productId; - }); - changedProductOptions = changedProductOptions && changedProductOptions.options && - changedProductOptions.options.reduce(function (obj, val) { - obj[val['option_id']] = val['option_value']; - - return obj; - }, {}); - - if (JSON.stringify(productOptions || {}) === JSON.stringify(changedProductOptions || {})) { - return false; - } - - productOptions = changedProductOptions; - - return true; - }; + swatchWidget._EmulateSelectedByAttributeId(this.productOptions); + }, + updater = new Updater(widgetInitEvent, updateSwatchOptions); - cartData.subscribe(function (updateCartData) { - if (setProductOptions(updateCartData)) { - updateSwatchOptions(); - } - }); - $(selectors.formSelector).on('swatch.initialized', function () { - setProductOptions(cartData()); - updateSwatchOptions(); - }); + updater.listen(); }); -- GitLab From 210fcb2d1eb0aa70c7b79841c9ea0c168fff4a9d Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 2 Sep 2016 12:53:30 +0300 Subject: [PATCH 801/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- dev/tests/functional/utils/generate.php | 3 --- lib/internal/Magento/Framework/App/State.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/dev/tests/functional/utils/generate.php b/dev/tests/functional/utils/generate.php index 78cf8cad069..e374dae4ccf 100644 --- a/dev/tests/functional/utils/generate.php +++ b/dev/tests/functional/utils/generate.php @@ -9,9 +9,6 @@ require_once dirname(__FILE__) . '/' . 'bootstrap.php'; $magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER); $magentoObjectManager = $magentoObjectManagerFactory->create($_SERVER); -// Generate repositories -$magentoObjectManager->get(\Magento\Framework\App\State::class)->setAreaCode('frontend'); - // Generate factories for old end-to-end tests $magentoObjectManager->create(\Magento\Mtf\Util\Generate\Factory::class)->launch(); diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index 0a759deb447..de4b21b70da 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -198,7 +198,7 @@ class State private function checkAreaCode($areaCode) { $areaCodes = array_merge( - [Area::AREA_GLOBAL, Area::AREA_ADMIN, Area::AREA_FRONTEND, Area::AREA_ADMINHTML], + [Area::AREA_GLOBAL, Area::AREA_ADMIN], $this->getAreaListInstance()->getCodes() ); -- GitLab From 5448233594d94688b146564d7bdb882d6e88058a Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 2 Sep 2016 14:55:57 +0300 Subject: [PATCH 802/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- .../Console/Command/ImagesResizeCommand.php | 48 +++++++------------ .../Observer/AfterAddressSaveObserverTest.php | 2 +- .../Magento/Store/Model/App/Emulation.php | 2 +- lib/internal/Magento/Framework/App/Area.php | 6 ++- lib/internal/Magento/Framework/App/State.php | 2 +- .../src/Magento/Setup/Controller/Session.php | 2 +- .../Setup/Mvc/Bootstrap/InitParamListener.php | 2 +- 7 files changed, 28 insertions(+), 36 deletions(-) diff --git a/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php b/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php index 3a3c80f9987..fdddb048cb6 100644 --- a/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php +++ b/app/code/Magento/Catalog/Console/Command/ImagesResizeCommand.php @@ -5,29 +5,15 @@ */ namespace Magento\Catalog\Console\Command; -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Image\Cache as ImageCache; -use Magento\Catalog\Model\Product\Image\CacheFactory as ImageCacheFactory; -use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; -use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory; -use Magento\Framework\App\State as AppState; -use Magento\Framework\Exception\NoSuchEntityException; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class ImagesResizeCommand extends Command +class ImagesResizeCommand extends \Symfony\Component\Console\Command\Command { /** - * @var AppState + * @var \Magento\Framework\App\State */ protected $appState; /** - * @var ProductCollectionFactory + * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory */ protected $productCollectionFactory; @@ -37,21 +23,21 @@ class ImagesResizeCommand extends Command protected $productRepository; /** - * @var ImageCacheFactory + * @var \Magento\Catalog\Model\Product\Image\CacheFactory */ protected $imageCacheFactory; /** - * @param AppState $appState - * @param ProductCollectionFactory $productCollectionFactory + * @param \Magento\Framework\App\State $appState + * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository - * @param ImageCacheFactory $imageCacheFactory + * @param \Magento\Catalog\Model\Product\Image\CacheFactory $imageCacheFactory */ public function __construct( - AppState $appState, - ProductCollectionFactory $productCollectionFactory, + \Magento\Framework\App\State $appState, + \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory, \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, - ImageCacheFactory $imageCacheFactory + \Magento\Catalog\Model\Product\Image\CacheFactory $imageCacheFactory ) { $this->appState = $appState; $this->productCollectionFactory = $productCollectionFactory; @@ -72,11 +58,13 @@ class ImagesResizeCommand extends Command /** * {@inheritdoc} */ - protected function execute(InputInterface $input, OutputInterface $output) - { + protected function execute( + \Symfony\Component\Console\Input\InputInterface $input, + \Symfony\Component\Console\Output\OutputInterface $output + ) { $this->appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); - /** @var ProductCollection $productCollection */ + /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */ $productCollection = $this->productCollectionFactory->create(); $productIds = $productCollection->getAllIds(); if (!count($productIds)) { @@ -88,13 +76,13 @@ class ImagesResizeCommand extends Command try { foreach ($productIds as $productId) { try { - /** @var Product $product */ + /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productRepository->getById($productId); - } catch (NoSuchEntityException $e) { + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { continue; } - /** @var ImageCache $imageCache */ + /** @var \Magento\Catalog\Model\Product\Image\Cache $imageCache */ $imageCache = $this->imageCacheFactory->create(); $imageCache->generate($product); diff --git a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php index 5e9e532c8a5..f05349946ba 100644 --- a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php +++ b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php @@ -587,7 +587,7 @@ class AfterAddressSaveObserverTest extends \PHPUnit_Framework_TestCase 'country_id' => 1, 'country_code' => 'US', 'group_id' => 1, - 'area_code' => Area::AREA_ADMIN, + 'area_code' => Area::AREA_ADMINHTML, 'is_vat_valid' => false, 'request_sucess' => false, 'valid_message' => '', diff --git a/app/code/Magento/Store/Model/App/Emulation.php b/app/code/Magento/Store/Model/App/Emulation.php index 6d85b9e8b3a..69cf3eedb02 100644 --- a/app/code/Magento/Store/Model/App/Emulation.php +++ b/app/code/Magento/Store/Model/App/Emulation.php @@ -235,7 +235,7 @@ class Emulation extends \Magento\Framework\DataObject */ protected function _restoreInitialLocale( $initialLocaleCode, - $initialArea = \Magento\Framework\App\Area::AREA_ADMIN + $initialArea = \Magento\Framework\App\Area::AREA_ADMINHTML ) { $this->_localeResolver->setLocale($initialLocaleCode); $this->_translate->setLocale($initialLocaleCode); diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php index 20dbbe01d9f..984b745a159 100644 --- a/lib/internal/Magento/Framework/App/Area.php +++ b/lib/internal/Magento/Framework/App/Area.php @@ -17,13 +17,17 @@ class Area implements \Magento\Framework\App\AreaInterface { const AREA_GLOBAL = 'global'; const AREA_FRONTEND = 'frontend'; - const AREA_ADMIN = 'admin'; const AREA_ADMINHTML = 'adminhtml'; const AREA_DOC = 'doc'; const AREA_CRONTAB = 'crontab'; const AREA_WEBAPI_REST = 'webapi_rest'; const AREA_WEBAPI_SOAP = 'webapi_soap'; + /** + * @deprecated + */ + const AREA_ADMIN = 'admin'; + /** * Area parameter. */ diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index de4b21b70da..965c9e706ed 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -198,7 +198,7 @@ class State private function checkAreaCode($areaCode) { $areaCodes = array_merge( - [Area::AREA_GLOBAL, Area::AREA_ADMIN], + [Area::AREA_GLOBAL], $this->getAreaListInstance()->getCodes() ); diff --git a/setup/src/Magento/Setup/Controller/Session.php b/setup/src/Magento/Setup/Controller/Session.php index 371365d11b6..f7ac8e4abd1 100644 --- a/setup/src/Magento/Setup/Controller/Session.php +++ b/setup/src/Magento/Setup/Controller/Session.php @@ -58,7 +58,7 @@ class Session extends AbstractActionController $objectManager = $this->objectManagerProvider->get(); /** @var \Magento\Framework\App\State $adminAppState */ $adminAppState = $objectManager->get(\Magento\Framework\App\State::class); - $adminAppState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMIN); + $adminAppState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML); $sessionConfig = $objectManager->get(\Magento\Backend\Model\Session\AdminConfig::class); /** @var \Magento\Backend\Model\Url $backendUrl */ $backendUrl = $objectManager->get(\Magento\Backend\Model\Url::class); diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php index 149cfe61a55..6a4b3a72b37 100644 --- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php +++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php @@ -122,7 +122,7 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface $objectManager = $objectManagerProvider->get(); /** @var \Magento\Framework\App\State $adminAppState */ $adminAppState = $objectManager->get(\Magento\Framework\App\State::class); - $adminAppState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMIN); + $adminAppState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML); /** @var \Magento\Backend\Model\Session\AdminConfig $sessionConfig */ $sessionConfig = $objectManager->get(\Magento\Backend\Model\Session\AdminConfig::class); $cookiePath = $this->getSetupCookiePath($objectManager); -- GitLab From ac3b6ad381dc017c943ec8541360f8c42a1df54f Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Fri, 2 Sep 2016 15:20:57 +0300 Subject: [PATCH 803/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- setup/src/Magento/Setup/Controller/Session.php | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/setup/src/Magento/Setup/Controller/Session.php b/setup/src/Magento/Setup/Controller/Session.php index f7ac8e4abd1..34441bc4a70 100644 --- a/setup/src/Magento/Setup/Controller/Session.php +++ b/setup/src/Magento/Setup/Controller/Session.php @@ -5,11 +5,7 @@ */ namespace Magento\Setup\Controller; -use Zend\Mvc\Controller\AbstractActionController; -use Zend\View\Model\JsonModel; -use Zend\View\Model\ViewModel; - -class Session extends AbstractActionController +class Session extends \Zend\Mvc\Controller\AbstractActionController { /** * @var \Zend\ServiceManager\ServiceManager @@ -36,11 +32,11 @@ class Session extends AbstractActionController /** * No index action, return 404 error page * - * @return ViewModel|\Zend\Http\Response + * @return \Zend\View\Model\ViewModel|\Zend\Http\Response */ public function indexAction() { - $view = new ViewModel; + $view = new \Zend\View\Model\ViewModel; $view->setTemplate('/error/404.phtml'); $this->getResponse()->setStatusCode(\Zend\Http\Response::STATUS_CODE_404); return $view; @@ -74,19 +70,19 @@ class Session extends AbstractActionController ] ); $session->prolong(); - return new JsonModel(['success' => true]); + return new \Zend\View\Model\JsonModel(['success' => true]); } } catch (\Exception $e) { } - return new JsonModel(['success' => false]); + return new \Zend\View\Model\JsonModel(['success' => false]); } /** - * @return ViewModel|\Zend\Http\Response + * @return \Zend\View\Model\ViewModel|\Zend\Http\Response */ public function unloginAction() { - $view = new ViewModel(); + $view = new \Zend\View\Model\ViewModel(); $view->setTemplate('/error/401.phtml'); $this->getResponse()->setStatusCode(\Zend\Http\Response::STATUS_CODE_401); return $view; -- GitLab From ac22f4fbb34486ebac9f1f39fd24b459fc4238c5 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@magento.com> Date: Fri, 2 Sep 2016 15:27:50 +0300 Subject: [PATCH 804/838] MAGETWO-55433: [Github # 6294] Coupon code override cart rules with no coupon code --- .../SalesRule/Model/ResourceModel/Rule/CollectionTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php index 0b75f5c8657..fc70361638b 100644 --- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/ResourceModel/Rule/CollectionTest.php @@ -42,15 +42,15 @@ class CollectionTest extends \PHPUnit_Framework_TestCase public function setValidationFilterDataProvider() { return [ - 'Check type COUPON' => ['coupon_code', ['#1', '#5']], + 'Check type COUPON' => ['coupon_code', ['#1', '#2', '#5']], 'Check type NO_COUPON' => ['', ['#2', '#5']], - 'Check type COUPON_AUTO' => ['coupon_code_auto', ['#4', '#5']], - 'Check result with auto generated coupon' => ['autogenerated_3_1', ['#3', '#5']], + 'Check type COUPON_AUTO' => ['coupon_code_auto', ['#2', '#4', '#5']], + 'Check result with auto generated coupon' => ['autogenerated_3_1', ['#2', '#3', '#5']], 'Check result with non actual previously generated coupon' => [ 'autogenerated_2_1', ['#2', '#5'], ], - 'Check result with wrong code' => ['wrong_code', ['#5']] + 'Check result with wrong code' => ['wrong_code', ['#2', '#5']] ]; } -- GitLab From fa38ed768520bcae9a3a683265a2861353c1f990 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko <yonischenko@magento.com> Date: Fri, 2 Sep 2016 16:05:33 +0300 Subject: [PATCH 805/838] MAGETWO-57805: [mainline] It is possible to delete self admin account or role --- app/code/Magento/User/Controller/Adminhtml/User/Delete.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Delete.php b/app/code/Magento/User/Controller/Adminhtml/User/Delete.php index 570cf4132c6..d892c8533a2 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Delete.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Delete.php @@ -14,8 +14,8 @@ class Delete extends \Magento\User\Controller\Adminhtml\User public function execute() { $currentUser = $this->_objectManager->get(\Magento\Backend\Model\Auth\Session::class)->getUser(); - - if ($userId = (int)$this->getRequest()->getPost('user_id')) { + $userId = (int)$this->getRequest()->getPost('user_id'); + if ($userId) { if ($currentUser->getId() == $userId) { $this->messageManager->addError(__('You cannot delete your own account.')); $this->_redirect('adminhtml/*/edit', ['user_id' => $userId]); -- GitLab From 911ec9353658428a77fd09be0a03add79054b2e4 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 2 Sep 2016 17:26:33 +0300 Subject: [PATCH 806/838] MAGETWO-55184: [GitHub #5526]Selected category is not added to Cart Price Rule condition due to JS error --- .../Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php index 8fca36fc673..dd71453c5ed 100644 --- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php +++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php @@ -64,7 +64,6 @@ class Edit extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote $model->getActionsFieldSetId($model->getActions()->getFormName()) ); - $resultPage->getLayout()->getBlock('promo_sales_rule_edit_tab_coupons')->setCanShow(true); } -- GitLab From 624ee867d568fff6aa4badf46a869506b3350baf Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 2 Sep 2016 12:36:14 -0500 Subject: [PATCH 807/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 9 ++++----- .../Magento/Framework/Test/Unit/EscaperTest.php | 15 ++++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index f979ed5e5a8..783d2829c45 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -23,12 +23,12 @@ class Escaper /** * @var string[] */ - private $notAllowedTags = ['script', 'img']; + private $notAllowedTags = ['script', 'img', 'embed', 'iframe', 'video', 'source', 'object', 'audio']; /** * @var string[] */ - private $allowedAttributes = ['id', 'class', 'href', 'target', 'title']; + private $allowedAttributes = ['id', 'class', 'href', 'target', 'title', 'style']; /** * @var string[] @@ -59,7 +59,7 @@ class Escaper $this->getLogger()->critical( 'The following tag(s) are not allowed: ' . implode(', ', $notAllowedTags) ); - return ''; + $allowedTags = array_diff($allowedTags, $this->notAllowedTags); } $wrapperElementId = uniqid(); $domDocument = new \DOMDocument('1.0', 'UTF-8'); @@ -76,7 +76,6 @@ class Escaper } catch (\Exception $e) { restore_error_handler(); $this->getLogger()->critical($e); - return $this->escapeHtml($data); } restore_error_handler(); @@ -87,7 +86,7 @@ class Escaper $result = mb_convert_encoding($domDocument->saveHTML(), 'UTF-8', 'HTML-ENTITIES'); preg_match('/<body id="' . $wrapperElementId . '">(.+)<\/body><\/html>$/si', $result, $matches); - return $matches[1]; + return !empty($matches) ? $matches[1] : ''; } else { $result = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', false); } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 32875903908..2d15510baeb 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -219,13 +219,18 @@ class EscaperTest extends \PHPUnit_Framework_TestCase 'allowedTags' => ['span', 'b'], ], 'text with non ascii characters' => [ - 'data' => ['абвгд', 'مثال'], - 'expected' => ['абвгд', 'مثال'], + 'data' => ['абвгд', 'مثال', '幸ç¦'], + 'expected' => ['абвгд', 'مثال', '幸ç¦'], 'allowedTags' => [], ], 'html and body tags' => [ 'data' => '<html><body><span>String</span></body></html>', - 'expected' => '<html><body><span>String</span></body></html>', + 'expected' => '<span>String</span>', + 'allowedTags' => ['span'], + ], + 'invalid tag' => [ + 'data' => '<some tag> some text', + 'expected' => ' some text', 'allowedTags' => ['span'], ], ]; @@ -239,12 +244,12 @@ class EscaperTest extends \PHPUnit_Framework_TestCase return [ 'text with allowed script tag' => [ 'data' => '<span><script>some text in tags</script></span>', - 'expected' => '', + 'expected' => '<span>some text in tags</span>', 'allowedTags' => ['span', 'script'], ], 'text with invalid html' => [ 'data' => '<spa>n id="id1">Some string</span>', - 'expected' => '<spa>n id="id1">Some string</span>', + 'expected' => 'n id="id1">Some string', 'allowedTags' => ['span'], ], ]; -- GitLab From cb30704c8e535aa4726ec56fa710568dcfc9dd7c Mon Sep 17 00:00:00 2001 From: Igor Melnikov <imelnikov@magento.com> Date: Fri, 2 Sep 2016 12:46:17 -0500 Subject: [PATCH 808/838] MAGETWO-57271: Modify escapeHtml function to filter not allowed attributes and tags Modifying function to filter not allowed tags and attributes --- lib/internal/Magento/Framework/Escaper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 783d2829c45..512b3b813cd 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -36,7 +36,8 @@ class Escaper private $escapeAsUrlAttributes = ['href']; /** - * Escape string for HTML context, allowedTags will not be escaped + * Escape string for HTML context. allowedTags will not be escaped, except the following: script, img, embed, + * iframe, video, source, object, audio * * @param string|array $data * @param array|null $allowedTags -- GitLab From 64d65a4a05b90219b8d3fe40c927853e0370a94f Mon Sep 17 00:00:00 2001 From: Bohdan Korablov <bkorablov@magento.com> Date: Mon, 5 Sep 2016 13:09:19 +0300 Subject: [PATCH 809/838] MAGETWO-45357: Nonexistent Area is Set in Setup Application --- lib/internal/Magento/Framework/App/State.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/App/State.php b/lib/internal/Magento/Framework/App/State.php index 965c9e706ed..c7206030f84 100644 --- a/lib/internal/Magento/Framework/App/State.php +++ b/lib/internal/Magento/Framework/App/State.php @@ -213,6 +213,7 @@ class State * Get Instance of AreaList * * @return AreaList + * @deprecated */ private function getAreaListInstance() { -- GitLab From eadafa20637c971fd8c9e0bd85a1af69145e9110 Mon Sep 17 00:00:00 2001 From: Yurii Hryhoriev <yhryhoriev@magento.com> Date: Mon, 5 Sep 2016 16:33:46 +0300 Subject: [PATCH 810/838] MAGETWO-56054: [GitHub] Admin >New order: 'Recently Viewed Products' has 0 price value #5810 --- .../Adminhtml/Order/Create/AbstractCreate.php | 16 ++++- .../Order/Create/AbstractCreateTest.php | 70 +++++++++++++++++++ .../order/create/sidebar/items.phtml | 2 +- 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Create/AbstractCreateTest.php diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/AbstractCreate.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/AbstractCreate.php index 9c46fdd7f93..31540762c95 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/AbstractCreate.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/AbstractCreate.php @@ -6,6 +6,8 @@ namespace Magento\Sales\Block\Adminhtml\Order\Create; use Magento\Framework\Pricing\PriceCurrencyInterface; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Pricing\Price\FinalPrice; /** * Adminhtml sales order create abstract block @@ -130,12 +132,22 @@ abstract class AbstractCreate extends \Magento\Backend\Block\Widget ); } + /** + * @param Product $product + * @return string + */ + public function getItemPrice(Product $product) + { + $price = $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue(); + return $this->convertPrice($price); + } + /** * Convert price * - * @param float $value + * @param int|float $value * @param bool $format - * @return float + * @return string|int|float */ public function convertPrice($value, $format = true) { diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Create/AbstractCreateTest.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Create/AbstractCreateTest.php new file mode 100644 index 00000000000..cd3187d2092 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Create/AbstractCreateTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Test\Unit\Block\Adminhtml\Order\Create; + +use Magento\Catalog\Pricing\Price\FinalPrice; + +class AbstractCreateTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate|\PHPUnit_Framework_MockObject_MockObject + */ + protected $model; + + /** + * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + */ + protected $productMock; + + /** + * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject + */ + protected $priceInfoMock; + + /** + * @var \Magento\Downloadable\Pricing\Price\LinkPrice|\PHPUnit_Framework_MockObject_MockObject + */ + protected $linkPriceMock; + + protected function setUp() + { + $this->model = $this->getMockBuilder(\Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate::class) + ->setMethods(['convertPrice']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->priceInfoMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo\Base::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->getMock(); + $this->linkPriceMock = $this->getMockBuilder(\Magento\Downloadable\Pricing\Price\LinkPrice::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productMock->expects($this->any()) + ->method('getPriceInfo') + ->willReturn($this->priceInfoMock); + } + + public function testGetItemPrice() + { + $price = 5.6; + $resultPrice = 9.3; + + $this->linkPriceMock->expects($this->once()) + ->method('getValue') + ->willReturn($price); + $this->priceInfoMock->expects($this->once()) + ->method('getPrice') + ->with(FinalPrice::PRICE_CODE) + ->willReturn($this->linkPriceMock); + $this->model->expects($this->once()) + ->method('convertPrice') + ->with($price) + ->willReturn($resultPrice); + $this->assertEquals($resultPrice, $this->model->getItemPrice($this->productMock)); + } +} diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml index 19a2a7e1a85..b04c374209e 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml @@ -66,7 +66,7 @@ <?php endif; ?> <?php if ($block->canDisplayPrice()): ?> - <td class="col-price"><?php /* @escapeNotVerified */ echo $block->convertPrice($_item->getPrice()) ?></td> + <td class="col-price"><?php echo $block->getItemPrice($_item) ?></td> <?php endif; ?> <?php if ($block->canRemoveItems()): ?> -- GitLab From 629a4a4599620b119348efd37b1b99bb18bda8eb Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Mon, 5 Sep 2016 18:39:29 +0300 Subject: [PATCH 811/838] MAGETWO-56534: CLONE - Price in cart does not update correctly when price is changed in admin. --- app/code/Magento/Quote/etc/di.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml index c4b1f9d1ce8..7ff9a385fca 100644 --- a/app/code/Magento/Quote/etc/di.xml +++ b/app/code/Magento/Quote/etc/di.xml @@ -92,8 +92,7 @@ <preference for="Magento\Quote\Model\Product\QuoteItemsCleanerInterface" type="Magento\Quote\Model\Product\QuoteItemsCleaner" /> <type name="Magento\Catalog\Model\ResourceModel\Product"> <plugin name="clean_quote_items_after_product_delete" type="Magento\Quote\Model\Product\Plugin\RemoveQuoteItems"/> - </type> - <type name="Magento\Catalog\Model\ResourceModel\Product"> <plugin name="update_quote_items_after_product_save" type="Magento\Quote\Model\Product\Plugin\UpdateQuoteItems"/> </type> + </type> </config> -- GitLab From 24ae3a4085cc5bc9b6026714e942e11678122aa5 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Mon, 5 Sep 2016 18:46:57 +0300 Subject: [PATCH 812/838] MAGETWO-56534: CLONE - Price in cart does not update correctly when price is changed in admin. --- app/code/Magento/Quote/etc/di.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml index 7ff9a385fca..6fb03921396 100644 --- a/app/code/Magento/Quote/etc/di.xml +++ b/app/code/Magento/Quote/etc/di.xml @@ -94,5 +94,4 @@ <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> </config> -- GitLab From ad677791a0f47aa957e2f75c142e1fd5488ff365 Mon Sep 17 00:00:00 2001 From: Olga Kopylova <okopylova@magento.com> Date: Mon, 5 Sep 2016 11:43:49 -0500 Subject: [PATCH 813/838] MAGETWO-56104: Build stablization - fixed MCHI --- .../Test/Unit/Block/Account/AuthenticationPopupTest.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php b/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php index f0ec5ec9148..10191c68485 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Account/AuthenticationPopupTest.php @@ -14,15 +14,12 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ class AuthenticationPopupTest extends \PHPUnit_Framework_TestCase { - /** @var AuthenticationPopup */ + /** @var \Magento\Customer\Block\Account\AuthenticationPopup */ private $model; - /** @var Context|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject */ private $contextMock; /** @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ -- GitLab From a22846cae1904c7a399d34f0565b03d1fa2c019a Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Mon, 5 Sep 2016 19:51:34 +0300 Subject: [PATCH 814/838] MAGETWO-56534: CLONE - Price in cart does not update correctly when price is changed in admin. --- .../Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php | 4 ++-- .../Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php index efc7f8c5b0a..c3fff344205 100644 --- a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php +++ b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php @@ -24,14 +24,14 @@ class UpdateQuoteItems /** * @param \Magento\Catalog\Model\ResourceModel\Product $subject * @param \Closure $proceed - * @param \Magento\Catalog\Api\Data\ProductInterface $product + * @param \Magento\Framework\Model\AbstractModel $product * @return mixed * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function aroundSave( \Magento\Catalog\Model\ResourceModel\Product $subject, \Closure $proceed, - \Magento\Catalog\Api\Data\ProductInterface $product + \Magento\Framework\Model\AbstractModel $product ) { $result = $proceed($product); $originalPrice = $product->getOrigData('price'); diff --git a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php index 12d79a6da5e..41a14b0f78f 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php @@ -34,9 +34,9 @@ class UpdateQuoteItemsTest extends \PHPUnit_Framework_TestCase public function testAroundUpdate($originalPrice, $newPrice, $callMethod) { $productResourceMock = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false); - $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) + $productMock = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class) ->disableOriginalConstructor() - ->setMethods(['getOrigData']) + ->setMethods(['getOrigData', 'getPrice', 'getId']) ->getMockForAbstractClass(); $closure = function () use ($productResourceMock) { return $productResourceMock; -- GitLab From 05d2b3aa67925772414f860213d55333b7012c98 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Tue, 24 May 2016 16:13:26 +0300 Subject: [PATCH 815/838] MAGETWO-51447: CatalogSearch Fulltext Collection not allows to use filters with multiple values --- .../Product/Indexer/Eav/AbstractEav.php | 2 + .../ResourceModel/Fulltext/Collection.php | 4 +- .../Model/Search/IndexBuilder.php | 2 +- .../Model/Search/TableMapper.php | 47 ++++- .../ResourceModel/Fulltext/CollectionTest.php | 176 ++++++++++++++---- .../Unit/Model/Search/IndexBuilderTest.php | 2 +- .../Unit/Model/Search/TableMapperTest.php | 28 ++- .../Framework/Search/Adapter/Mysql/Mapper.php | 1 + .../Test/Unit/Adapter/Mysql/MapperTest.php | 8 +- 9 files changed, 205 insertions(+), 65 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php index 3cc635a3c1b..d9612f18c91 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/AbstractEav.php @@ -263,6 +263,8 @@ abstract class AbstractEav extends \Magento\Catalog\Model\ResourceModel\Product\ 'ca.is_filterable_in_search > 0', 'ca.is_visible_in_advanced_search > 0', 'ca.is_filterable > 0', + // Visibility is attribute that isn't used by search, but required to determine is product should be shown + "ea.attribute_code = 'visibility'" ]; return implode(' OR ', $conditions); diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index a563bfab62e..8a9e2b19174 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -265,7 +265,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection $this->getSearchCriteriaBuilder(); $this->getFilterBuilder(); - if (!is_array($condition) || !in_array(key($condition), ['from', 'to'])) { + if (!is_array($condition) || !in_array(key($condition), ['from', 'to'], true)) { $this->filterBuilder->setField($field); $this->filterBuilder->setValue($condition); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); @@ -371,7 +371,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection public function setOrder($attribute, $dir = Select::SQL_DESC) { $this->order = ['field' => $attribute, 'dir' => $dir]; - if ($attribute != 'relevance') { + if ($attribute !== 'relevance') { parent::setOrder($attribute, $dir); } return $this; diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php index c332332beb7..1d30bb4a14d 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php @@ -123,7 +123,7 @@ class IndexBuilder implements IndexBuilderInterface ScopeInterface::SCOPE_STORE ); if ($isShowOutOfStock === false) { - $select->joinLeft( + $select->joinInner( ['stock_index' => $this->resource->getTableName('cataloginventory_stock_status')], 'search_index.entity_id = stock_index.product_id' . $this->resource->getConnection()->quoteInto( diff --git a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php index d4f371e965e..712afeeb295 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php @@ -6,8 +6,11 @@ namespace Magento\CatalogSearch\Model\Search; +use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; +use Magento\Eav\Model\Config as EavConfig; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ResourceConnection as AppResource; use Magento\Framework\DB\Select; use Magento\Framework\Search\Request\FilterInterface; @@ -34,41 +37,64 @@ class TableMapper /** * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection + * @deprecated */ private $attributeCollection; + /** + * @var EavConfig + */ + private $eavConfig; + /** * @param AppResource $resource * @param StoreManagerInterface $storeManager * @param CollectionFactory $attributeCollectionFactory + * @param EavConfig $eavConfig */ public function __construct( AppResource $resource, StoreManagerInterface $storeManager, - CollectionFactory $attributeCollectionFactory + CollectionFactory $attributeCollectionFactory, + EavConfig $eavConfig = null ) { $this->resource = $resource; $this->storeManager = $storeManager; $this->attributeCollection = $attributeCollectionFactory->create(); + $this->eavConfig = $eavConfig !== null ? $eavConfig : ObjectManager::getInstance()->get(EavConfig::class); } /** * @param Select $select * @param RequestInterface $request * @return Select + * @throws \LogicException */ public function addTables(Select $select, RequestInterface $request) { $mappedTables = []; $filters = $this->getFilters($request->getQuery()); foreach ($filters as $filter) { - list($alias, $table, $mapOn, $mappedFields) = $this->getMappingData($filter); + list($alias, $table, $mapOn, $mappedFields, $joinType) = $this->getMappingData($filter); if (!array_key_exists($alias, $mappedTables)) { - $select->joinLeft( - [$alias => $table], - $mapOn, - $mappedFields - ); + switch ($joinType) { + case \Magento\Framework\DB\Select::INNER_JOIN: + $select->joinInner( + [$alias => $table], + $mapOn, + $mappedFields + ); + break; + case \Magento\Framework\DB\Select::LEFT_JOIN: + $select->joinLeft( + [$alias => $table], + $mapOn, + $mappedFields + ); + break; + default: + throw new \LogicException(__('Unsupported join type: %1', $joinType)); + } $mappedTables[$alias] = $table; } } @@ -102,6 +128,7 @@ class TableMapper $mapOn = null; $mappedFields = null; $field = $filter->getField(); + $joinType = \Magento\Framework\DB\Select::INNER_JOIN; $fieldToTableMap = $this->getFieldToTableMap($field); if ($fieldToTableMap) { list($alias, $table, $mapOn, $mappedFields) = $fieldToTableMap; @@ -110,6 +137,7 @@ class TableMapper if ($filter->getType() === FilterInterface::TYPE_TERM && in_array($attribute->getFrontendInput(), ['select', 'multiselect'], true) ) { + $joinType = \Magento\Framework\DB\Select::LEFT_JOIN; $table = $this->resource->getTableName('catalog_product_index_eav'); $alias = $field . RequestGenerator::FILTER_SUFFIX; $mapOn = sprintf( @@ -127,7 +155,7 @@ class TableMapper } } - return [$alias, $table, $mapOn, $mappedFields]; + return [$alias, $table, $mapOn, $mappedFields, $joinType]; } /** @@ -242,10 +270,11 @@ class TableMapper /** * @param string $field * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute + * @throws \Magento\Framework\Exception\LocalizedException */ private function getAttributeByCode($field) { - $attribute = $this->attributeCollection->getItemByColumnValue('attribute_code', $field); + $attribute = $this->eavConfig->getAttribute(Product::ENTITY, $field); return $attribute; } } diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php index fc75aec23d6..84430c56476 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php @@ -6,12 +6,49 @@ namespace Magento\CatalogSearch\Test\Unit\Model\ResourceModel\Fulltext; use Magento\CatalogSearch\Test\Unit\Model\ResourceModel\BaseCollectionTest; +use Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory; +use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class CollectionTest extends BaseCollectionTest { + /** + * @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorage|\PHPUnit_Framework_MockObject_MockObject + */ + private $temporaryStorage; + + /** + * @var \Magento\Search\Api\SearchInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $search; + + /** + * @var MockObject + */ + private $criteriaBuilder; + + /** + * @var MockObject + */ + private $storeManager; + + /** + * @var MockObject + */ + private $universalFactory; + + /** + * @var MockObject + */ + private $scopeConfig; + + /** + * @var MockObject + */ + private $filterBuilder; + /** * @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection */ @@ -29,32 +66,48 @@ class CollectionTest extends BaseCollectionTest { $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $storeManager = $this->getStoreManager(); - $universalFactory = $this->getUniversalFactory(); - $scopeConfig = $this->getScopeConfig(); - $criteriaBuilder = $this->getCriteriaBuilder(); - $filterBuilder = $this->getFilterBuilder(); + $this->storeManager = $this->getStoreManager(); + $this->universalFactory = $this->getUniversalFactory(); + $this->scopeConfig = $this->getScopeConfig(); + $this->criteriaBuilder = $this->getCriteriaBuilder(); + $this->filterBuilder = $this->getFilterBuilder(); + + $this->prepareObjectManager( + [ + [ + \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class, + $this->getMock(\Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class) + ], + ] + ); - $this->prepareObjectManager([ - [\Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class, - $this->getMock(\Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class) - ], - ]); + $this->temporaryStorage = $this->getMockBuilder(\Magento\Framework\Search\Adapter\Mysql\TemporaryStorage::class) + ->disableOriginalConstructor() + ->getMock(); + $temporaryStorageFactory = $this->getMockBuilder(TemporaryStorageFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $temporaryStorageFactory->expects($this->any()) + ->method('create') + ->willReturn($this->temporaryStorage); $this->model = $helper->getObject( \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection::class, [ - 'storeManager' => $storeManager, - 'universalFactory' => $universalFactory, - 'scopeConfig' => $scopeConfig, + 'storeManager' => $this->storeManager, + 'universalFactory' => $this->universalFactory, + 'scopeConfig' => $this->scopeConfig, + 'temporaryStorageFactory' => $temporaryStorageFactory ] ); - $search = $this->getMockForAbstractClass(\Magento\Search\Api\SearchInterface::class); - $this->model->setSearchCriteriaBuilder($criteriaBuilder); - $this->model->setSearch($search); - $this->model->setFilterBuilder($filterBuilder); - + $this->search = $this->getMockBuilder(\Magento\Search\Api\SearchInterface::class) + ->setMethods(['search']) + ->getMockForAbstractClass(); + $this->model->setSearchCriteriaBuilder($this->criteriaBuilder); + $this->model->setSearch($this->search); + $this->model->setFilterBuilder($this->filterBuilder); } /** @@ -62,13 +115,50 @@ class CollectionTest extends BaseCollectionTest * @expectedExceptionCode 333 * @expectedExceptionMessage setRequestName */ - public function testGetFacetedData() + public function testGetFacetedDataWithException() + { + $criteria = $this->getMock(\Magento\Framework\Api\Search\SearchCriteria::class, [], [], '', false); + $this->criteriaBuilder->expects($this->once())->method('create')->willReturn($criteria); + $criteria->expects($this->once()) + ->method('setRequestName') + ->withConsecutive(['catalog_view_container']) + ->willThrowException(new \Exception('setRequestName', 333)); + $this->model->getFacetedData('field'); + } + + public function testGetFacetedDataWithEmptyAggregations() { + $criteria = $this->getMock(\Magento\Framework\Api\Search\SearchCriteria::class, [], [], '', false); + $this->criteriaBuilder->expects($this->once())->method('create')->willReturn($criteria); + $criteria->expects($this->once()) + ->method('setRequestName') + ->withConsecutive(['catalog_view_container']); + $searchResult = $this->getMockBuilder(\Magento\Framework\Api\Search\SearchResultInterface::class) + ->getMockForAbstractClass(); + $table = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class) + ->setMethods(['getName']) + ->getMock(); + $this->temporaryStorage->expects($this->once()) + ->method('storeApiDocuments') + ->willReturn($table); + $this->search->expects($this->once()) + ->method('search') + ->willReturn($searchResult); $this->model->getFacetedData('field'); } + public function testAddFieldToFilter() + { + $this->filter = $this->createFilter(); + $this->criteriaBuilder->expects($this->once()) + ->method('addFilter') + ->with($this->filter); + $this->filterBuilder->expects($this->once())->method('create')->willReturn($this->filter); + $this->model->addFieldToFilter('someMultiselectValue', [3, 5, 8]); + } + /** - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function getScopeConfig() { @@ -76,15 +166,12 @@ class CollectionTest extends BaseCollectionTest ->setMethods(['getValue']) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $scopeConfig->expects($this->once()) - ->method('getValue') - ->willReturn(1); return $scopeConfig; } /** - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function getCriteriaBuilder() { @@ -92,31 +179,32 @@ class CollectionTest extends BaseCollectionTest ->setMethods(['addFilter', 'create', 'setRequestName']) ->disableOriginalConstructor() ->getMock(); - $this->filter = new \Magento\Framework\Api\Filter(); - $this->filter->setField('price_dynamic_algorithm'); - $this->filter->setValue(1); - $criteriaBuilder->expects($this->once()) - ->method('addFilter') - ->with($this->filter); - $criteria = $this->getMock(\Magento\Framework\Api\Search\SearchCriteria::class, [], [], '', false); - $criteriaBuilder->expects($this->once())->method('create')->willReturn($criteria); - $criteria->expects($this->once()) - ->method('setRequestName') - ->withConsecutive(['catalog_view_container']) - ->willThrowException(new \Exception('setRequestName', 333)); return $criteriaBuilder; } /** - * @return \PHPUnit_Framework_MockObject_MockObject + * @return MockObject */ protected function getFilterBuilder() { $filterBuilder = $this->getMock(\Magento\Framework\Api\FilterBuilder::class, [], [], '', false); - $filterBuilder->expects($this->once())->method('setField')->with('price_dynamic_algorithm'); - $filterBuilder->expects($this->once())->method('setValue')->with(1); - $filterBuilder->expects($this->once())->method('create')->willReturn($this->filter); + return $filterBuilder; + } + + protected function addFiltersToFilterBuilder(MockObject $filterBuilder, array $filters) + { + $i = 1; + foreach ($filters as $field => $value) { + $filterBuilder->expects($this->at($i++)) + ->method('setField') + ->with($field) + ->willReturnSelf(); + $filterBuilder->expects($this->at($i++)) + ->method('setValue') + ->with($value) + ->willReturnSelf(); + } return $filterBuilder; } @@ -135,4 +223,12 @@ class CollectionTest extends BaseCollectionTest $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($objectManagerMock); } + + protected function createFilter() + { + $filter = $this->getMockBuilder(\Magento\Framework\Api\Filter::class) + ->disableOriginalConstructor() + ->getMock(); + return $filter; + } } 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 1356df9e18c..8b98ab9c4cc 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php @@ -226,7 +226,7 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase ->with('(someName=someValue)') ->willReturnSelf(); $this->select->expects($this->at(3)) - ->method('joinLeft') + ->method('joinInner') ->with( ['stock_index' => 'cataloginventory_stock_status'], 'search_index.entity_id = stock_index.product_id' 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 9c117dc7dcf..bf4205a5dd0 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php @@ -19,6 +19,11 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase const WEBSITE_ID = 4512; const STORE_ID = 2514; + /** + * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject + */ + private $eavConfig; + /** * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection|\PHPUnit_Framework_MockObject_MockObject */ @@ -127,12 +132,19 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase $attributeCollectionFactory->expects($this->once()) ->method('create') ->willReturn($this->attributeCollection); + $this->attributeCollection->expects($this->never()) + ->method('getItemByColumnValue'); + $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) + ->setMethods(['getAttribute']) + ->disableOriginalConstructor() + ->getMock(); $this->target = $objectManager->getObject( \Magento\CatalogSearch\Model\Search\TableMapper::class, [ 'resource' => $this->resource, 'storeManager' => $this->storeManager, - 'attributeCollectionFactory' => $attributeCollectionFactory + 'attributeCollectionFactory' => $attributeCollectionFactory, + 'eavConfig' => $this->eavConfig, ] ); @@ -152,7 +164,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->method('getQuery') ->willReturn($query); $this->select->expects($this->once()) - ->method('joinLeft') + ->method('joinInner') ->with( ['price_index' => 'prefix_catalog_product_index_price'], 'search_index.entity_id = price_index.entity_id AND price_index.website_id = ' . self::WEBSITE_ID, @@ -172,7 +184,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->method('getQuery') ->willReturn($query); $this->select->expects($this->once()) - ->method('joinLeft') + ->method('joinInner') ->with( ['static_filter' => 'backend_table'], 'search_index.entity_id = static_filter.entity_id', @@ -191,7 +203,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->method('getQuery') ->willReturn($query); $this->select->expects($this->once()) - ->method('joinLeft') + ->method('joinInner') ->with( ['category_ids_index' => 'prefix_catalog_category_product_index'], 'search_index.entity_id = category_ids_index.product_id', @@ -309,7 +321,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ) ->willReturnSelf(); $this->select->expects($this->at(1)) - ->method('joinLeft') + ->method('joinInner') ->with( ['price_index' => 'prefix_catalog_product_index_price'], 'search_index.entity_id = price_index.entity_id AND price_index.website_id = ' . self::WEBSITE_ID, @@ -586,9 +598,9 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->willReturn($backendTable); $attribute->method('getFrontendInput') ->willReturn($frontendInput); - $this->attributeCollection->expects($this->at($positionInCollection)) - ->method('getItemByColumnValue') - ->with('attribute_code', $code) + $this->eavConfig->expects($this->at($positionInCollection)) + ->method('getAttribute') + ->with(\Magento\Catalog\Model\Product::ENTITY, $code) ->willReturn($attribute); } } diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php index 0db1e3ff763..064271f189b 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php @@ -158,6 +158,7 @@ class Mapper private function createAroundSelect(Select $select, ScoreBuilder $scoreBuilder) { $parentSelect = $this->getConnection()->select(); + $select->limit(10000000000); // MySQL 5.7 workaround $parentSelect->from( ['main_select' => $select], [ diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/MapperTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/MapperTest.php index 4f2a931f1b4..ef1d7a6ee54 100644 --- a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/MapperTest.php +++ b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/MapperTest.php @@ -145,7 +145,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->once())->method('getQuery')->will($this->returnValue($query)); - $select->expects($this->any())->method('columns')->will($this->returnValue($select)); + $select->expects($this->any())->method('columns')->willReturnSelf(); $response = $this->mapper->buildQuery($this->request); @@ -165,7 +165,7 @@ class MapperTest extends \PHPUnit_Framework_TestCase ->method('getSize') ->willReturn(self::REQUEST_LIMIT); - $select->expects($this->any())->method('columns')->will($this->returnValue($select)); + $select->expects($this->any())->method('columns')->willReturnSelf(); $this->request->expects($this->once())->method('getQuery')->will($this->returnValue($query)); @@ -522,9 +522,9 @@ class MapperTest extends \PHPUnit_Framework_TestCase ->willReturnSelf(); } - $select->expects($isInternal ? $this->once() : $this->never()) + $select->expects($this->any()) ->method('limit') - ->with(self::REQUEST_LIMIT) + ->with($isInternal ? self::REQUEST_LIMIT : 10000000000) ->willReturnSelf(); $select->expects($isInternal ? $this->once() : $this->never()) ->method('order') -- GitLab From 22b078aedcad4e04d66522eb533ccc6f9b58c112 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Wed, 25 May 2016 13:56:28 +0300 Subject: [PATCH 816/838] MAGETWO-51447: CatalogSearch Fulltext Collection not allows to use filters with multiple values --- .../CatalogSearch/Model/Search/TableMapper.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php index 712afeeb295..ca7298e1bea 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php +++ b/app/code/Magento/CatalogSearch/Model/Search/TableMapper.php @@ -35,18 +35,13 @@ class TableMapper */ private $storeManager; - /** - * @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection - * @deprecated - */ - private $attributeCollection; - /** * @var EavConfig */ private $eavConfig; /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @param AppResource $resource * @param StoreManagerInterface $storeManager * @param CollectionFactory $attributeCollectionFactory @@ -60,7 +55,6 @@ class TableMapper ) { $this->resource = $resource; $this->storeManager = $storeManager; - $this->attributeCollection = $attributeCollectionFactory->create(); $this->eavConfig = $eavConfig !== null ? $eavConfig : ObjectManager::getInstance()->get(EavConfig::class); } @@ -116,7 +110,8 @@ class TableMapper * 'table_alias', * 'table', * 'join_condition', - * ['fields'] + * ['fields'], + * 'joinType' * ] * @param FilterInterface $filter * @return array -- GitLab From d21edaf91652e11d5fc89bd54fe5aafae154560f Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Thu, 26 May 2016 10:28:09 +0300 Subject: [PATCH 817/838] MAGETWO-51447: CatalogSearch Fulltext Collection not allows to use filters with multiple values - Fix unit test --- .../Test/Unit/Model/Search/TableMapperTest.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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 bf4205a5dd0..48270909629 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php @@ -119,7 +119,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->method('getStore') ->willReturn($this->store); $this->attributeCollection = $this->getMockBuilder( - \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class + '\Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection' ) ->disableOriginalConstructor() ->getMock(); @@ -129,11 +129,8 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); - $attributeCollectionFactory->expects($this->once()) - ->method('create') - ->willReturn($this->attributeCollection); - $this->attributeCollection->expects($this->never()) - ->method('getItemByColumnValue'); + $attributeCollectionFactory->expects($this->never()) + ->method('create'); $this->eavConfig = $this->getMockBuilder(\Magento\Eav\Model\Config::class) ->setMethods(['getAttribute']) ->disableOriginalConstructor() -- GitLab From 909ebdaea79e7426187fb64f358a1e9816a19e14 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Tue, 6 Sep 2016 09:06:39 +0300 Subject: [PATCH 818/838] MAGETWO-51447: CatalogSearch Fulltext Collection not allows to use filters with multiple values - Use ::class notation instead of string literal --- .../CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 48270909629..dd9a556146a 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/TableMapperTest.php @@ -119,7 +119,7 @@ class TableMapperTest extends \PHPUnit_Framework_TestCase ->method('getStore') ->willReturn($this->store); $this->attributeCollection = $this->getMockBuilder( - '\Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection' + \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection::class ) ->disableOriginalConstructor() ->getMock(); -- GitLab From c2a4d8354fd48773b73e2f2cc32a7a5e8c60ff63 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Tue, 6 Sep 2016 10:02:22 +0300 Subject: [PATCH 819/838] MAGETWO-51447: CatalogSearch Fulltext Collection not allows to use filters with multiple values - Remove outdated workaround for MySQL 5.7 --- lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php index 064271f189b..0db1e3ff763 100644 --- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php +++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Mapper.php @@ -158,7 +158,6 @@ class Mapper private function createAroundSelect(Select $select, ScoreBuilder $scoreBuilder) { $parentSelect = $this->getConnection()->select(); - $select->limit(10000000000); // MySQL 5.7 workaround $parentSelect->from( ['main_select' => $select], [ -- GitLab From 21c8a66997d73783bb4f6c1ed227c873578ec1d6 Mon Sep 17 00:00:00 2001 From: Maksym Iakusha <miakusha@magento.com> Date: Mon, 22 Aug 2016 14:13:34 +0300 Subject: [PATCH 820/838] MAGETWO-55847: [GitHub] When tier price qty above 1000 adds a thousand separator in the Admin Panel #5745 --- .../Product/Form/Modifier/General.php | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) 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 7b54a508b81..ce5ac077c52 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 @@ -82,7 +82,7 @@ class General extends AbstractModifier $data = $this->arrayManager->replace( $path, $data, - $this->formatNumber($this->arrayManager->get($path, $data)) + $this->formatWeight($this->arrayManager->get($path, $data)) ); } @@ -105,7 +105,7 @@ class General extends AbstractModifier $value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE] = $this->formatPrice($value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE]); $value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE_QTY] = - $this->formatNumber((int)$value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE_QTY]); + (int)$value[ProductAttributeInterface::CODE_TIER_PRICE_FIELD_PRICE_QTY]; } } @@ -378,23 +378,6 @@ class General extends AbstractModifier return $this->localeCurrency; } - /** - * The getter function to get the store manager for real application code - * - * @return \Magento\Store\Model\StoreManagerInterface - * - * @deprecated - */ - private function getStoreManager() - { - if ($this->storeManager === null) { - $this->storeManager = - \Magento\Framework\App\ObjectManager::getInstance()->get(StoreManagerInterface::class); - } - return $this->storeManager; - } - - /** * Format price according to the locale of the currency * @@ -407,7 +390,7 @@ class General extends AbstractModifier return null; } - $store = $this->getStoreManager()->getStore(); + $store = $this->locator->getStore(); $currency = $this->getLocaleCurrency()->getCurrency($store->getBaseCurrencyCode()); $value = $currency->toCurrency($value, ['display' => \Magento\Framework\Currency::NO_SYMBOL]); @@ -428,7 +411,7 @@ class General extends AbstractModifier $value = (float)$value; $precision = strlen(substr(strrchr($value, "."), 1)); - $store = $this->getStoreManager()->getStore(); + $store = $this->locator->getStore(); $currency = $this->getLocaleCurrency()->getCurrency($store->getBaseCurrencyCode()); $value = $currency->toCurrency($value, ['display' => \Magento\Framework\Currency::NO_SYMBOL, 'precision' => $precision]); -- GitLab From 310808f4cba92da528f646acf85be576934b1eed Mon Sep 17 00:00:00 2001 From: Maksym Iakusha <miakusha@magento.com> Date: Mon, 22 Aug 2016 14:20:22 +0300 Subject: [PATCH 821/838] MAGETWO-55847: [GitHub] When tier price qty above 1000 adds a thousand separator in the Admin Panel #5745 --- .../Ui/DataProvider/Product/Form/Modifier/General.php | 6 ------ 1 file changed, 6 deletions(-) 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 ce5ac077c52..ea0c6275875 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 @@ -9,7 +9,6 @@ use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Ui\Component\Form; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Locale\CurrencyInterface; /** @@ -26,11 +25,6 @@ class General extends AbstractModifier * @var ArrayManager */ protected $arrayManager; - - /** - * @var StoreManagerInterface - */ - private $storeManager; /** * @var CurrencyInterface -- GitLab From 9d33182bbab1f70e304611575082fe241643a4d8 Mon Sep 17 00:00:00 2001 From: Maksym Iakusha <miakusha@magento.com> Date: Mon, 22 Aug 2016 15:41:07 +0300 Subject: [PATCH 822/838] MAGETWO-55847: [GitHub] When tier price qty above 1000 adds a thousand separator in the Admin Panel #5745 --- .../Catalog/Ui/DataProvider/Product/Form/Modifier/General.php | 2 ++ 1 file changed, 2 insertions(+) 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 ea0c6275875..ab22e4aeb3d 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 @@ -13,6 +13,8 @@ use Magento\Framework\Locale\CurrencyInterface; /** * Data provider for main panel of product page + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class General extends AbstractModifier { -- GitLab From 807667e61717cce32d3ec95014e55053247870c1 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Wed, 31 Aug 2016 19:40:30 +0300 Subject: [PATCH 823/838] MAGETWO-57175: Cannot delete product image --- .../Model/Product/Gallery/ReadHandler.php | 2 +- .../Model/Product/Gallery/ReadHandlerTest.php | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php index 8a3109f3507..28ecfff39c9 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/ReadHandler.php @@ -78,7 +78,7 @@ class ReadHandler implements ExtensionInterface foreach ($mediaEntries as $mediaEntry) { $mediaEntry = $this->substituteNullsWithDefaultValues($mediaEntry); - $value['images'][] = $mediaEntry; + $value['images'][$mediaEntry['value_id']] = $mediaEntry; } $product->setData($attrCode, $value); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php index 8a14d1e6a85..5c9a2f1e896 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php @@ -61,11 +61,18 @@ class ReadHandlerTest extends \PHPUnit_Framework_TestCase $this->assertArrayHasKey('media_gallery', $data); $this->assertArrayHasKey('images', $data['media_gallery']); - $image = array_shift($data['media_gallery']['images']); - $this->assertEquals( - 'Image Alt Text', - $image['label'] - ); + $this->assertCount(1, $data['media_gallery']['images']); + foreach ($data['media_gallery']['images'] as $valueId => $imageData) { + $this->assertEquals( + 'Image Alt Text', + $imageData['label'] + ); + $this->assertEquals( + $imageData['value_id'], + $valueId, + "Required by Magento/Catalog/view/adminhtml/templates/catalog/product/helper/gallery.phtml" + ); + } } } -- GitLab From fcb612d580e529f69b93cb8e5c637e36170b1c68 Mon Sep 17 00:00:00 2001 From: Maksym Aposov <maposov@magento.com> Date: Thu, 1 Sep 2016 15:35:34 +0300 Subject: [PATCH 824/838] MAGETWO-57175: Cannot delete product image --- .../Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php index 5c9a2f1e896..541256864c4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/ReadHandlerTest.php @@ -70,8 +70,7 @@ class ReadHandlerTest extends \PHPUnit_Framework_TestCase ); $this->assertEquals( $imageData['value_id'], - $valueId, - "Required by Magento/Catalog/view/adminhtml/templates/catalog/product/helper/gallery.phtml" + $valueId ); } } -- GitLab From 34f3520531e0663264fb1fb6d5bbfd8082556489 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov <lpoluyanov@magento.com> Date: Tue, 6 Sep 2016 12:21:35 +0300 Subject: [PATCH 825/838] MAGETWO-56534: CLONE - Price in cart does not update correctly when price is changed in admin. --- .../Quote/Model/Product/Plugin/UpdateQuoteItems.php | 9 ++++----- .../Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php | 7 ++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php index c3fff344205..c6062e351db 100644 --- a/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php +++ b/app/code/Magento/Quote/Model/Product/Plugin/UpdateQuoteItems.php @@ -23,17 +23,16 @@ class UpdateQuoteItems /** * @param \Magento\Catalog\Model\ResourceModel\Product $subject - * @param \Closure $proceed + * @param \Magento\Catalog\Model\ResourceModel\Product $result * @param \Magento\Framework\Model\AbstractModel $product - * @return mixed + * @return \Magento\Catalog\Model\ResourceModel\Product * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundSave( + public function afterSave( \Magento\Catalog\Model\ResourceModel\Product $subject, - \Closure $proceed, + \Magento\Catalog\Model\ResourceModel\Product $result, \Magento\Framework\Model\AbstractModel $product ) { - $result = $proceed($product); $originalPrice = $product->getOrigData('price'); if (!empty($originalPrice) && ($originalPrice != $product->getPrice())) { $this->resource->markQuotesRecollect($product->getId()); diff --git a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php index 41a14b0f78f..53015669816 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Product/Plugin/UpdateQuoteItemsTest.php @@ -31,22 +31,19 @@ class UpdateQuoteItemsTest extends \PHPUnit_Framework_TestCase * @param int $newPrice * @param bool $callMethod */ - public function testAroundUpdate($originalPrice, $newPrice, $callMethod) + public function testAfterUpdate($originalPrice, $newPrice, $callMethod) { $productResourceMock = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false); $productMock = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class) ->disableOriginalConstructor() ->setMethods(['getOrigData', 'getPrice', 'getId']) ->getMockForAbstractClass(); - $closure = function () use ($productResourceMock) { - return $productResourceMock; - }; $productId = 1; $productMock->expects($this->any())->method('getOrigData')->with('price')->willReturn($originalPrice); $productMock->expects($this->any())->method('getPrice')->willReturn($newPrice); $productMock->expects($this->any())->method('getId')->willReturn($productId); $this->quoteResource->expects($this->$callMethod())->method('markQuotesRecollect')->with($productId); - $result = $this->model->aroundSave($productResourceMock, $closure, $productMock); + $result = $this->model->afterSave($productResourceMock, $productResourceMock, $productMock); $this->assertEquals($result, $productResourceMock); } -- GitLab From 9389dad358a53c22c53c9fe6ca9d1e882c19b299 Mon Sep 17 00:00:00 2001 From: Yurii Hryhoriev <yhryhoriev@magento.com> Date: Tue, 6 Sep 2016 12:29:31 +0300 Subject: [PATCH 826/838] MAGETWO-56054: [GitHub] Admin >New order: 'Recently Viewed Products' has 0 price value #5810 - statics fix --- .../view/adminhtml/templates/order/create/sidebar/items.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml index b04c374209e..59bb31a94fa 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/sidebar/items.phtml @@ -66,7 +66,7 @@ <?php endif; ?> <?php if ($block->canDisplayPrice()): ?> - <td class="col-price"><?php echo $block->getItemPrice($_item) ?></td> + <td class="col-price"><?php /* @noEscape */ echo $block->getItemPrice($_item) ?></td> <?php endif; ?> <?php if ($block->canRemoveItems()): ?> -- GitLab From c5a612a92288eb23d6f6140602b0492e5047779b Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Tue, 6 Sep 2016 16:24:04 +0300 Subject: [PATCH 827/838] MAGETWO-56814: Unable to print Invoices and Credit memo from Sales>Orders --- .../Order/PdfDocumentsMassAction.php | 52 ++++++++ .../Adminhtml/Order/Pdfcreditmemos.php | 2 +- .../Adminhtml/Order/Pdfinvoices.php | 4 +- .../Adminhtml/PdfDocumentsMassActionTest.php | 114 ++++++++++++++++++ 4 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/Sales/Controller/Adminhtml/Order/PdfDocumentsMassAction.php create mode 100644 app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/PdfDocumentsMassActionTest.php diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/PdfDocumentsMassAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/PdfDocumentsMassAction.php new file mode 100644 index 00000000000..5396a1d69bc --- /dev/null +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/PdfDocumentsMassAction.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Controller\Adminhtml\Order; + +use Magento\Framework\Controller\ResultFactory; + +abstract class PdfDocumentsMassAction extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction +{ + /** + * @var \Magento\Sales\Model\ResourceModel\Order\CollectionFactory + */ + protected $orderCollectionFactory; + + /** + * Execute action + * + * @return \Magento\Backend\Model\View\Result\Redirect + * @throws \Magento\Framework\Exception\LocalizedException|\Exception + */ + public function execute() + { + try { + $collection = $this->filter->getCollection($this->getOrderCollection()->create()); + return $this->massAction($collection); + } catch (\Exception $e) { + $this->messageManager->addError($e->getMessage()); + /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); + return $resultRedirect->setPath($this->redirectUrl); + } + } + + /** + * Get Order Collection Factory + * + * @return \Magento\Sales\Model\ResourceModel\Order\CollectionFactory + * @deprecated + */ + private function getOrderCollection() + { + if ($this->orderCollectionFactory === null) { + $this->orderCollectionFactory = \Magento\Framework\App\ObjectManager::getInstance()->get( + \Magento\Sales\Model\ResourceModel\Order\CollectionFactory::class + ); + } + return $this->orderCollectionFactory; + } +} diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php index 119333e85f3..9b2e62ed96e 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php @@ -21,7 +21,7 @@ use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection; * Class Pdfcreditmemos * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Pdfcreditmemos extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction +class Pdfcreditmemos extends \Magento\Sales\Controller\Adminhtml\Order\PdfDocumentsMassAction { /** * @var FileFactory diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php index 8085f8fa406..4eb93fb332f 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php @@ -20,7 +20,7 @@ use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Pdfinvoices extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction +class Pdfinvoices extends \Magento\Sales\Controller\Adminhtml\Order\PdfDocumentsMassAction { /** * @var FileFactory @@ -79,7 +79,7 @@ class Pdfinvoices extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMass return $this->resultRedirectFactory->create()->setPath($this->getComponentRefererUrl()); } return $this->fileFactory->create( - sprintf('packingslip%s.pdf', $this->dateTime->date('Y-m-d_H-i-s')), + sprintf('invoice%s.pdf', $this->dateTime->date('Y-m-d_H-i-s')), $this->pdfInvoice->getPdf($invoicesCollection->getItems())->render(), DirectoryList::VAR_DIR, 'application/pdf' diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/PdfDocumentsMassActionTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/PdfDocumentsMassActionTest.php new file mode 100644 index 00000000000..e93c22fb837 --- /dev/null +++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/PdfDocumentsMassActionTest.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Sales\Test\Unit\Controller\Adminhtml; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; + +class PdfDocumentsMassActionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sales\Controller\Adminhtml\Order\PdfDocumentsMassAction + */ + private $controller; + + /** + * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject + */ + private $resultRedirect; + + /** + * @var \Magento\Framework\Message\Manager|\PHPUnit_Framework_MockObject_MockObject + */ + private $messageManager; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $orderCollectionFactoryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $orderCollectionMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $filterMock; + + protected function setUp() + { + $objectManagerHelper = new ObjectManagerHelper($this); + + $this->messageManager = $this->getMock( + \Magento\Framework\Message\Manager::class, + ['addSuccess', 'addError'], + [], + '', + false + ); + + $this->orderCollectionMock = $this->getMock( + \Magento\Sales\Model\ResourceModel\Order\Collection::class, + [], + [], + '', + false + ); + $this->filterMock = $this->getMock(\Magento\Ui\Component\MassAction\Filter::class, [], [], '', false); + + $this->orderCollectionFactoryMock = $this->getMock( + \Magento\Sales\Model\ResourceModel\Order\CollectionFactory::class, + ['create'], + [], + '', + false + ); + + $this->orderCollectionFactoryMock + ->expects($this->once()) + ->method('create') + ->willReturn($this->orderCollectionMock); + $this->resultRedirect = $this->getMock(\Magento\Backend\Model\View\Result\Redirect::class, [], [], '', false); + $resultRedirectFactory = $this->getMock( + \Magento\Framework\Controller\ResultFactory::class, + [], + [], + '', + false + ); + $resultRedirectFactory->expects($this->any())->method('create')->willReturn($this->resultRedirect); + $this->controller = $objectManagerHelper->getObject( + \Magento\Sales\Controller\Adminhtml\Order\Pdfinvoices::class, + [ + 'filter' => $this->filterMock, + 'resultFactory' => $resultRedirectFactory, + 'messageManager' => $this->messageManager + ] + ); + $objectManagerHelper + ->setBackwardCompatibleProperty( + $this->controller, + 'orderCollectionFactory', + $this->orderCollectionFactoryMock + ); + } + + public function testExecute() + { + $exception = new \Exception(); + $this->filterMock + ->expects($this->once()) + ->method('getCollection') + ->with($this->orderCollectionMock) + ->willThrowException($exception); + $this->messageManager->expects($this->once())->method('addError'); + + $this->resultRedirect->expects($this->once())->method('setPath')->willReturnSelf(); + $this->controller->execute($exception); + } +} -- GitLab From 3e070060cfe99fea8d824aff65fad7d59d33a2a7 Mon Sep 17 00:00:00 2001 From: Illia Grybkov <igrybkov@magento.com> Date: Wed, 7 Sep 2016 10:39:19 +0300 Subject: [PATCH 828/838] MAGETWO-55847: [GitHub] When tier price qty above 1000 adds a thousand separator in the Admin Panel #5745 - Remove suppress --- .../Ui/DataProvider/Product/Form/Modifier/General.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) 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 ab22e4aeb3d..0fbba264f7e 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 @@ -9,12 +9,9 @@ use Magento\Catalog\Api\Data\ProductAttributeInterface; use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Ui\Component\Form; use Magento\Framework\Stdlib\ArrayManager; -use Magento\Framework\Locale\CurrencyInterface; /** * Data provider for main panel of product page - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class General extends AbstractModifier { @@ -29,7 +26,7 @@ class General extends AbstractModifier protected $arrayManager; /** - * @var CurrencyInterface + * @var \Magento\Framework\Locale\CurrencyInterface */ private $localeCurrency; @@ -369,7 +366,8 @@ class General extends AbstractModifier private function getLocaleCurrency() { if ($this->localeCurrency === null) { - $this->localeCurrency = \Magento\Framework\App\ObjectManager::getInstance()->get(CurrencyInterface::class); + $this->localeCurrency = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Locale\CurrencyInterface::class); } return $this->localeCurrency; } -- GitLab From febd2bd92e16f178c03f9988a91f98d57b43abbd Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Wed, 7 Sep 2016 11:25:48 +0300 Subject: [PATCH 829/838] MAGETWO-55380: Information hint block for Zip/Postal Code should NOT block request for available shipping solution --- .../view/frontend/web/js/model/shipping-rates-validator.js | 5 ++--- 1 file changed, 2 insertions(+), 3 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 e002823fef1..55678fc701d 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 @@ -127,9 +127,8 @@ define( element.on('value', function () { clearTimeout(self.validateAddressTimeout); self.validateAddressTimeout = setTimeout(function () { - if (self.postcodeValidation()) { - self.validateFields(); - } + self.postcodeValidation(); + self.validateFields(); }, delay); }); observedElements.push(element); -- GitLab From 976dbc76e110c7aa47178e5bcddf6320bac4ef43 Mon Sep 17 00:00:00 2001 From: Arpita Barua <abarua@magento.com> Date: Wed, 7 Sep 2016 14:22:18 -0500 Subject: [PATCH 830/838] MAGETWO-55287: Missing product name in bundle product error message - Added changes for this bug --- .../Model/Quote/Item/QuantityValidator.php | 85 ++-- .../QuantityValidator/Initializer/Option.php | 1 + .../Initializer/OptionTest.php | 1 + .../Initializer/QuantityValidatorTest.php | 454 ++++++++++++++++++ .../Quote/Item/QuantityValidatorTest.php | 156 ++++++ 5 files changed, 659 insertions(+), 38 deletions(-) create mode 100644 app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php create mode 100644 dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index 0f28d9f26c3..6aa90b889bb 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -10,6 +10,9 @@ namespace Magento\CatalogInventory\Model\Quote\Item; use Magento\CatalogInventory\Api\StockRegistryInterface; use Magento\CatalogInventory\Api\StockStateInterface; +/** + * Class QuantityValidator + */ class QuantityValidator { /** @@ -23,20 +26,21 @@ class QuantityValidator protected $stockItemInitializer; /** - * @var StockRegistryInterface + * @var \Magento\CatalogInventory\Api\StockRegistryInterface */ protected $stockRegistry; /** - * @var StockStateInterface + * @var \Magento\CatalogInventory\Api\StockStateInterface */ protected $stockState; /** * @param QuantityValidator\Initializer\Option $optionInitializer * @param QuantityValidator\Initializer\StockItem $stockItemInitializer - * @param StockRegistryInterface $stockRegistry - * @param StockStateInterface $stockState + * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry + * @param \Magento\CatalogInventory\Api\StockStateInterface $stockState + * @return void */ public function __construct( QuantityValidator\Initializer\Option $optionInitializer, @@ -50,6 +54,30 @@ class QuantityValidator $this->stockState = $stockState; } + /** + * Add error information to Quote Item + * + * @param \Magento\Framework\DataObject $result + * @param \Magento\Quote\Model\Quote\Item $quoteItem + * @param bool $removeError + * @return void + */ + private function addErrorInfoToQuote($result, $quoteItem) + { + $quoteItem->addErrorInfo( + 'cataloginventory', + \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + $result->getMessage() + ); + + $quoteItem->getQuote()->addErrorInfo( + $result->getQuoteMessageIndex(), + 'cataloginventory', + \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + $result->getQuoteMessage() + ); + } + /** * Check product inventory data when quote item quantity declaring * @@ -81,7 +109,6 @@ class QuantityValidator $quoteItem->getProduct()->getId(), $quoteItem->getProduct()->getStore()->getWebsiteId() ); - /* @var $stockItem \Magento\CatalogInventory\Api\Data\StockItemInterface */ if (!$stockItem instanceof \Magento\CatalogInventory\Api\Data\StockItemInterface) { throw new \Magento\Framework\Exception\LocalizedException(__('The stock item for Product is not valid.')); } @@ -152,48 +179,30 @@ class QuantityValidator ); } } + // variable to keep track if we have previously encountered an error in one of the options + $removeError = true; foreach ($options as $option) { $result = $this->optionInitializer->initialize($option, $quoteItem, $qty); if ($result->getHasError()) { $option->setHasError(true); - - $quoteItem->addErrorInfo( - 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, - $result->getMessage() - ); - - $quoteItem->getQuote()->addErrorInfo( - $result->getQuoteMessageIndex(), - 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, - $result->getQuoteMessage() - ); - } else { - // Delete error from item and its quote, if it was set due to qty lack - $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); + //Setting this to false, so no error statuses are cleared + $removeError = false; + $this->addErrorInfoToQuote($result, $quoteItem, $removeError); } } - } else { - $result = $this->stockItemInitializer->initialize($stockItem, $quoteItem, $qty); - if ($result->getHasError()) { - $quoteItem->addErrorInfo( - 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, - $result->getMessage() - ); - - $quoteItem->getQuote()->addErrorInfo( - $result->getQuoteMessageIndex(), - 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, - $result->getQuoteMessage() - ); - } else { - // Delete error from item and its quote, if it was set due to qty lack + if ($removeError) { $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); } + } else { + if ($quoteItem->getParentItem() === null) { + $result = $this->stockItemInitializer->initialize($stockItem, $quoteItem, $qty); + if ($result->getHasError()) { + $this->addErrorInfoToQuote($result, $quoteItem); + } else { + $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); + } + } } } diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php index 41dbebda5cd..ef69379f25f 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator/Initializer/Option.php @@ -101,6 +101,7 @@ class Option ); $stockItem = $this->getStockItem($option, $quoteItem); + $stockItem->setProductName($option->getProduct()->getName()); $result = $this->stockState->checkQuoteItemQty( $option->getProduct()->getId(), $optionQty, diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php index b91f8a1fdb0..a55540c5c4b 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/OptionTest.php @@ -106,6 +106,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase '__wakeup', 'unsIsChildItem', 'getItemId', + 'setProductName' ]; $this->stockItemMock = $this->getMock( diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php new file mode 100644 index 00000000000..c11db1341a7 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php @@ -0,0 +1,454 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogInventory\Test\Unit\Model\Quote\Item\QuantityValidator\Initializer; + +/** + * Class QuantityValidatorTest + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class QuantityValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $quantityValidator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $stockRegistryMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $optionInitializer; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $observerMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $eventMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $quoteMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $storeMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $quoteItemMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $parentItemMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $productMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $stockItemMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $parentStockItemMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $typeInstanceMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $resultMock; + + protected function setUp() + { + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->stockRegistryMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockRegistry::class) + ->disableOriginalConstructor() + ->setMethods(['getStockItem']) + ->getMock(); + $this->optionInitializer = $this->getMockBuilder( + \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class + ) + ->disableOriginalConstructor() + ->getMock(); + $this->stockItemInitializer = $this->getMockBuilder( + \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem::class + ) + ->disableOriginalConstructor() + ->getMock(); + $this->stockState = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockState::class) + ->disableOriginalConstructor() + ->setMethods(['checkQtyIncrements', 'getHasError', 'getQuoteMessageIndex', 'getQuoteMessage']) + ->getMock(); + $this->quantityValidator = $objectManagerHelper->getObject( + \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::class, + [ + 'optionInitializer' => $this->optionInitializer, + 'stockItemInitializer' => $this->stockItemInitializer, + 'stockRegistry' => $this->stockRegistryMock, + 'stockState' => $this->stockState + ], + '', + false + ); + $this->observerMock = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) + ->disableOriginalConstructor() + ->setMethods(['getEvent']) + ->getMock(); + $this->eventMock = $this->getMockBuilder(\Magento\Framework\Event::class) + ->disableOriginalConstructor() + ->setMethods(['getItem']) + ->getMock(); + $this->quoteMock = $this->getMockBuilder(\Magento\Quote\Model\Quote::class) + ->disableOriginalConstructor() + ->setMethods(['getIsSuperMode', 'addErrorInfo', 'getQuote', 'getItemsCollection']) + ->getMock(); + $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + ->disableOriginalConstructor() + ->setMethods(['getWebsiteId']) + ->getMock(); + $this->quoteItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) + ->disableOriginalConstructor() + ->setMethods( + ['getProductId', 'getQuote', 'getQty', 'getProduct', 'getParentItem', + 'addErrorInfo', 'setData', 'getQtyOptions'] + ) + ->getMock(); + $this->parentItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getProduct', 'getId', 'getStore']) + ->getMock(); + $this->productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->setMethods(['getId', 'getStore', 'getTypeInstance']) + ->getMock(); + $this->stockItemMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\Stock\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getIsInStock']) + ->getMock(); + $this->parentStockItemMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\Stock\Item::class) + ->disableOriginalConstructor() + ->setMethods(['getIsInStock']) + ->getMock(); + $this->typeInstanceMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\Stock\Item::class) + ->disableOriginalConstructor() + ->setMethods(['prepareQuoteItemQty']) + ->getMock(); + $this->resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) + ->disableOriginalConstructor() + ->setMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) + ->getMock(); + } + + /** + * This tests the scenario when item is not in stock + * + * @return void + */ + public function testValidateOutOfStock() + { + $this->createInitialStub(0); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn($this->stockItemMock); + $this->stockItemMock->expects($this->once()) + ->method('getIsInStock') + ->willReturn(false); + $this->quoteItemMock->expects($this->once()) + ->method('addErrorInfo') + ->with( + 'cataloginventory', + \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + __('This product is out of stock.') + ); + $this->quoteMock->expects($this->once()) + ->method('addErrorInfo') + ->with( + 'stock', + 'cataloginventory', + \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + __('Some of the products are out of stock.') + ); + $this->quantityValidator->validate($this->observerMock); + } + + /** + * This tests the scenario when item is in stock but parent is not in stock + * + * @return void + */ + public function testValidateInStock() + { + $this->createInitialStub(1); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn($this->stockItemMock); + $this->stockRegistryMock->expects($this->at(1)) + ->method('getStockItem') + ->willReturn($this->parentStockItemMock); + $this->parentStockItemMock->expects($this->once()) + ->method('getIsInStock') + ->willReturn(false); + $this->quoteItemMock->expects($this->any()) + ->method('getParentItem') + ->willReturn($this->parentItemMock); + $this->stockItemMock->expects($this->once()) + ->method('getIsInStock') + ->willReturn(true); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn($this->stockItemMock); + $this->quoteItemMock->expects($this->once()) + ->method('addErrorInfo') + ->with( + 'cataloginventory', + \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + __('This product is out of stock.') + ); + $this->quoteMock->expects($this->once()) + ->method('addErrorInfo') + ->with( + 'stock', + 'cataloginventory', + \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + __('Some of the products are out of stock.') + ); + $this->quantityValidator->validate($this->observerMock); + } + + /** + * This tests the scenario when item is in stock and has options + * + * @return void + */ + public function testValidateWithOptions() + { + $optionMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item\Option::class) + ->disableOriginalConstructor() + ->setMethods(['setHasError']) + ->getMock(); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn($this->stockItemMock); + $options = [$optionMock]; + $this->createInitialStub(1); + $this->setUpStubForQuantity(1, true); + $this->setUpStubForRemoveError(); + $this->parentStockItemMock->expects($this->any()) + ->method('getIsInStock') + ->willReturn(true); + $this->stockItemMock->expects($this->once()) + ->method('getIsInStock') + ->willReturn(true); + $this->quoteItemMock->expects($this->any()) + ->method('getQtyOptions') + ->willReturn($options); + $this->optionInitializer->expects($this->any()) + ->method('initialize') + ->willReturn($this->resultMock); + $optionMock->expects($this->never()) + ->method('setHasError'); + $this->quantityValidator->validate($this->observerMock); + } + + /** + * This tests the scenario with options but has errors + * + * @return void + */ + public function testValidateWithOptionsAndError(){ + $optionMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item\Option::class) + ->disableOriginalConstructor() + ->setMethods(['setHasError']) + ->getMock(); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn($this->stockItemMock); + $options = [$optionMock]; + $this->createInitialStub(1); + $this->setUpStubForQuantity(1, true); + $this->setUpStubForRemoveError(); + $this->parentStockItemMock->expects($this->any()) + ->method('getIsInStock') + ->willReturn(true); + $this->stockItemMock->expects($this->once()) + ->method('getIsInStock') + ->willReturn(true); + $this->quoteItemMock->expects($this->any()) + ->method('getQtyOptions') + ->willReturn($options); + $this->optionInitializer->expects($this->any()) + ->method('initialize') + ->willReturn($this->resultMock); + $optionMock->expects($this->never()) + ->method('setHasError'); + $this->quantityValidator->validate($this->observerMock); + } + + /** + * This tests the scenario when all the items are both parent and item are in stock and any errors are cleared + * + * @return void + */ + public function testRemoveError() + { + $this->createInitialStub(1); + $this->setUpStubForRemoveError(); + $this->quoteItemMock->expects($this->any()) + ->method('getQtyOptions') + ->willReturn(null); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn($this->stockItemMock); + $this->quoteItemMock->expects($this->any()) + ->method('getParentItem') + ->willReturn($this->parentItemMock); + $this->stockItemMock->expects($this->once()) + ->method('getIsInStock') + ->willReturn(true); + $this->quoteItemMock->expects($this->never()) + ->method('addErrorInfo'); + $this->quoteMock->expects($this->never()) + ->method('addErrorInfo'); + $this->quantityValidator->validate($this->observerMock); + } + + /** + * This test the scenario when stock Item is not of correct type and throws appropriate exception + * + * @throws \Magento\Framework\Exception\LocalizedException + * @return void + */ + public function testException() + { + $this->createInitialStub(1); + $this->stockRegistryMock->expects($this->at(0)) + ->method('getStockItem') + ->willReturn(null); + $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class); + $this->quantityValidator->validate($this->observerMock); + } + + private function setUpStubForQuantity($qty, $hasError) + { + $this->productMock->expects($this->any()) + ->method('getTypeInstance') + ->willReturn($this->typeInstanceMock); + $this->typeInstanceMock->expects($this->any()) + ->method('prepareQuoteItemQty') + ->willReturn($qty); + $this->quoteItemMock->expects($this->any()) + ->method('setData'); + $this->productMock->expects($this->any()) + ->method('getId') + ->willReturn(1); + $this->stockState->expects($this->any()) + ->method('checkQtyIncrements') + ->willReturn($this->resultMock); + $this->resultMock->expects($this->any()) + ->method('getHasError') + ->willReturn($hasError); + $this->resultMock->expects($this->any()) + ->method('getMessage') + ->willReturn(''); + $this->resultMock->expects($this->any()) + ->method('getQuoteMessage') + ->willReturn(''); + $this->resultMock->expects($this->any()) + ->method('getQuoteMessageIndex') + ->willReturn(''); + } + + private function createInitialStub($qty) + { + $this->storeMock->expects($this->any()) + ->method('getWebsiteId') + ->willReturn(1); + $this->quoteMock->expects($this->any()) + ->method('getIsSuperMode') + ->willReturn(0); + $this->productMock->expects($this->any()) + ->method('getId') + ->willReturn(1); + $this->productMock->expects($this->any()) + ->method('getStore') + ->willReturn($this->storeMock); + $this->quoteItemMock->expects($this->any()) + ->method('getProductId') + ->willReturn(1); + $this->quoteItemMock->expects($this->any()) + ->method('getQuote') + ->willReturn($this->quoteMock); + $this->quoteItemMock->expects($this->once()) + ->method('getQty') + ->willReturn($qty); + $this->quoteItemMock->expects($this->any()) + ->method('getProduct') + ->willReturn($this->productMock); + $this->eventMock->expects($this->any()) + ->method('getItem') + ->willReturn($this->quoteItemMock); + $this->observerMock->expects($this->any()) + ->method('getEvent') + ->willReturn($this->eventMock); + $this->parentItemMock->expects($this->any()) + ->method('getProduct') + ->willReturn($this->productMock); + $this->parentStockItemMock->expects($this->any()) + ->method('getIsInStock') + ->willReturn(false); + $this->storeMock->expects($this->any()) + ->method('getWebsiteId') + ->willReturn(1); + $this->quoteItemMock->expects($this->any()) + ->method('getQuote') + ->willReturn($this->quoteMock); + $this->quoteMock->expects($this->any()) + ->method('getQuote') + ->willReturn($this->quoteMock); + $this->quoteItemMock->expects($this->any()) + ->method('addErrorInfo'); + $this->quoteMock->expects($this->any()) + ->method('addErrorInfo'); + $this->setUpStubForQuantity(0, false); + $this->stockItemInitializer->expects($this->any()) + ->method('initialize') + ->willReturn($this->resultMock); + } + + private function setUpStubForRemoveError(){ + $quoteItems = [$this->quoteItemMock]; + $this->quoteItemMock->expects($this->any()) + ->method('getHasError') + ->willReturn(false); + $this->quoteMock->expects($this->any()) + ->method('getItemsCollection') + ->willReturn($quoteItems); + $this->quoteMock->expects($this->any()) + ->method('getHasError') + ->willReturn(false); + } +} diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php new file mode 100644 index 00000000000..b2716333dd6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php @@ -0,0 +1,156 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogInventory\Model\Quote\Item; +use Magento\TestFramework\Helper\Bootstrap; + +class QuantityValidatorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator + */ + private $quantityValidator; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $observerMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $eventMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $optionInitializer; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $stockState; + + /** + * @var \Magento\CatalogInventory\Observer\QuantityValidatorObserver + */ + private $observer; + + protected function setUp() + { + /** @var \Magento\Framework\ObjectManagerInterface objectManager */ + $this->objectManager = Bootstrap::getObjectManager(); + $this->observerMock = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) + ->disableOriginalConstructor() + ->setMethods(['getEvent']) + ->getMock(); + $this->optionInitializer = $this->getMockBuilder( + \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class + ) + ->disableOriginalConstructor() + ->getMock(); + $this->stockState = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockState::class) + ->disableOriginalConstructor() + ->setMethods(['checkQtyIncrements', 'getHasError', 'getQuoteMessageIndex', 'getQuoteMessage']) + ->getMock(); + $this->quantityValidator = $this->objectManager->create( + \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::class, + [ + 'optionInitializer' => $this->optionInitializer, + 'stockState' => $this->stockState + ] + ); + $this->observer = $this->objectManager->create( + \Magento\CatalogInventory\Observer\QuantityValidatorObserver::class, + [ + 'quantityValidator' => $this->quantityValidator + ] + ); + $this->eventMock = $this->getMockBuilder(\Magento\Framework\Event::class) + ->disableOriginalConstructor() + ->setMethods(['getItem']) + ->getMock(); + } + + /** + * @magentoDataFixture Magento/Checkout/_files/quote_with_bundle_product.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ + public function testQuoteWithOptions() + { + /** @var $session \Magento\Checkout\Model\Session */ + $session = $this->objectManager->create(\Magento\Checkout\Model\Session::class); + + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + /** @var $product \Magento\Catalog\Model\Product */ + $product = $productRepository->get('bundle-product'); + $resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) + ->disableOriginalConstructor() + ->setMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) + ->getMock(); + $this->stockState->expects($this->any())->method('checkQtyIncrements')->willReturn($resultMock); + /* @var $quoteItem \Magento\Quote\Model\Quote\Item */ + $quoteItem = $this->_getQuoteItemIdByProductId($session->getQuote(), $product->getId()); + $this->observerMock->expects($this->once())->method('getEvent')->willReturn($this->eventMock); + $this->optionInitializer->expects($this->any())->method('initialize')->willReturn($resultMock); + $this->eventMock->expects($this->once())->method('getItem')->willReturn($quoteItem); + $this->observer->execute($this->observerMock); + $this->assertCount(0, $quoteItem->getErrorInfos(), 'Errors present in QuoteItem when expected 0 errors'); + } + + /** + * @magentoDataFixture Magento/Checkout/_files/quote_with_bundle_product.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ + public function testQuoteWithOptionsWithErrors() + { + /** @var $session \Magento\Checkout\Model\Session */ + $session = $this->objectManager->create(\Magento\Checkout\Model\Session::class); + /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + /** @var $product \Magento\Catalog\Model\Product */ + $product = $productRepository->get('bundle-product'); + /* @var $quoteItem \Magento\Quote\Model\Quote\Item */ + $quoteItem = $this->_getQuoteItemIdByProductId($session->getQuote(), $product->getId()); + $resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) + ->disableOriginalConstructor() + ->setMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) + ->getMock(); + $this->observerMock->expects($this->once())->method('getEvent')->willReturn($this->eventMock); + $this->eventMock->expects($this->once())->method('getItem')->willReturn($quoteItem); + $this->stockState->expects($this->any())->method('checkQtyIncrements')->willReturn($resultMock); + $this->optionInitializer->expects($this->any())->method('initialize')->willReturn($resultMock); + $resultMock->expects($this->any())->method('getHasError')->willReturn(true); + $this->observer->execute($this->observerMock); + $this->assertCount(2, $quoteItem->getErrorInfos(), 'Expected 2 errors in QuoteItem'); + } + + /** + * Gets \Magento\Quote\Model\Quote\Item from \Magento\Quote\Model\Quote by product id + * + * @param \Magento\Quote\Model\Quote $quote + * @param $productId + * @return \Magento\Quote\Model\Quote\Item + */ + private function _getQuoteItemIdByProductId($quote, $productId) + { + /** @var $quoteItems \Magento\Quote\Model\Quote\Item[] */ + $quoteItems = $quote->getAllItems(); + foreach ($quoteItems as $quoteItem) { + if ($productId == $quoteItem->getProductId()) { + return $quoteItem; + } + } + $this->fail('Test failed since no quoteItem found by productId '.$productId); + } +} \ No newline at end of file -- GitLab From 5450526d2662d5044368cf29066476355a16d951 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@magento.com> Date: Thu, 8 Sep 2016 11:54:24 +0300 Subject: [PATCH 831/838] MAGETWO-57992: Reloading page on checkout causes shipping method to go "undefined" - for mainline --- .../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 edbca0a510b..0fd1a4967f8 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 @@ -165,7 +165,7 @@ define( } if (!availableRate && window.checkoutConfig.selectedShippingMethod) { - availableRate = true; + availableRate = window.checkoutConfig.selectedShippingMethod; selectShippingMethodAction(window.checkoutConfig.selectedShippingMethod); } -- GitLab From e29ea9c9ba8d968d8dd2e60fb2543f388dabcf85 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 8 Sep 2016 15:54:11 +0300 Subject: [PATCH 832/838] MAGETWO-57842: [FT] Wrong selector for Allow Gift Options for items in Shopping Cart in CheckoutWithGiftMessagesTest --- .../Magento/GiftMessage/Test/Block/Cart/Item/GiftOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Cart/Item/GiftOptions.php b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Cart/Item/GiftOptions.php index 0320b3e9a60..0d008ef79e0 100644 --- a/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Cart/Item/GiftOptions.php +++ b/dev/tests/functional/tests/app/Magento/GiftMessage/Test/Block/Cart/Item/GiftOptions.php @@ -33,7 +33,7 @@ class GiftOptions extends Form * * @var string */ - protected $allowGiftOptions = '//a[contains(@class,"action-gift")][ancestor::tbody[contains(.,"%s")]]'; + protected $allowGiftOptions = '//*[contains(@class,"action-gift")][ancestor::tbody[contains(.,"%s")]]'; /** * Selector for apply Gift Message button on order -- GitLab From 2bd184527d46c2d3ec07a34332797c1a0d7e92d3 Mon Sep 17 00:00:00 2001 From: Arpita Barua <abarua@magento.com> Date: Thu, 8 Sep 2016 10:56:02 -0500 Subject: [PATCH 833/838] MAGETWO-55287: Missing product name in bundle product error message - Removing fully qualified namespace from the code. Importing the fully qualified namespace instead in the beginning of the file. --- .../Model/Quote/Item/QuantityValidator.php | 45 ++--- .../Initializer/QuantityValidatorTest.php | 154 +++++++++--------- .../Quote/Item/QuantityValidatorTest.php | 61 +++---- 3 files changed, 125 insertions(+), 135 deletions(-) rename dev/tests/integration/testsuite/Magento/CatalogInventory/{ => Model}/Quote/Item/QuantityValidatorTest.php (69%) diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index 6aa90b889bb..ca18b7ec904 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -9,7 +9,12 @@ namespace Magento\CatalogInventory\Model\Quote\Item; use Magento\CatalogInventory\Api\StockRegistryInterface; use Magento\CatalogInventory\Api\StockStateInterface; - +use Magento\Framework\Exception\LocalizedException; +use Magento\CatalogInventory\Api\Data\StockItemInterface; +use Magento\CatalogInventory\Helper\Data; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem; +use Magento\Framework\Event\Observer; /** * Class QuantityValidator */ @@ -36,15 +41,15 @@ class QuantityValidator protected $stockState; /** - * @param QuantityValidator\Initializer\Option $optionInitializer - * @param QuantityValidator\Initializer\StockItem $stockItemInitializer - * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry - * @param \Magento\CatalogInventory\Api\StockStateInterface $stockState + * @param Option $optionInitializer + * @param StockItem $stockItemInitializer + * @param StockRegistryInterface $stockRegistry + * @param StockStateInterface $stockState * @return void */ public function __construct( - QuantityValidator\Initializer\Option $optionInitializer, - QuantityValidator\Initializer\StockItem $stockItemInitializer, + Option $optionInitializer, + StockItem $stockItemInitializer, StockRegistryInterface $stockRegistry, StockStateInterface $stockState ) { @@ -66,14 +71,14 @@ class QuantityValidator { $quoteItem->addErrorInfo( 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, $result->getMessage() ); $quoteItem->getQuote()->addErrorInfo( $result->getQuoteMessageIndex(), 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, $result->getQuoteMessage() ); } @@ -89,7 +94,7 @@ class QuantityValidator * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function validate(\Magento\Framework\Event\Observer $observer) + public function validate(Observer $observer) { /* @var $quoteItem \Magento\Quote\Model\Quote\Item */ $quoteItem = $observer->getEvent()->getItem(); @@ -109,8 +114,8 @@ class QuantityValidator $quoteItem->getProduct()->getId(), $quoteItem->getProduct()->getStore()->getWebsiteId() ); - if (!$stockItem instanceof \Magento\CatalogInventory\Api\Data\StockItemInterface) { - throw new \Magento\Framework\Exception\LocalizedException(__('The stock item for Product is not valid.')); + if (!$stockItem instanceof StockItemInterface) { + throw new LocalizedException(__('The stock item for Product is not valid.')); } $parentStockItem = false; @@ -130,19 +135,19 @@ class QuantityValidator if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) { $quoteItem->addErrorInfo( 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, __('This product is out of stock.') ); $quoteItem->getQuote()->addErrorInfo( 'stock', 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, __('Some of the products are out of stock.') ); return; } else { // Delete error from item and its quote, if it was set due to item out of stock - $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); + $this->_removeErrorsFromQuoteAndItem($quoteItem, Data::ERROR_QTY); } } @@ -161,21 +166,21 @@ class QuantityValidator if ($result->getHasError()) { $quoteItem->addErrorInfo( 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY_INCREMENTS, + Data::ERROR_QTY_INCREMENTS, $result->getMessage() ); $quoteItem->getQuote()->addErrorInfo( $result->getQuoteMessageIndex(), 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY_INCREMENTS, + Data::ERROR_QTY_INCREMENTS, $result->getQuoteMessage() ); } else { // Delete error from item and its quote, if it was set due to qty problems $this->_removeErrorsFromQuoteAndItem( $quoteItem, - \Magento\CatalogInventory\Helper\Data::ERROR_QTY_INCREMENTS + Data::ERROR_QTY_INCREMENTS ); } } @@ -192,7 +197,7 @@ class QuantityValidator } } if ($removeError) { - $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); + $this->_removeErrorsFromQuoteAndItem($quoteItem, Data::ERROR_QTY); } } else { if ($quoteItem->getParentItem() === null) { @@ -200,7 +205,7 @@ class QuantityValidator if ($result->getHasError()) { $this->addErrorInfoToQuote($result, $quoteItem); } else { - $this->_removeErrorsFromQuoteAndItem($quoteItem, \Magento\CatalogInventory\Helper\Data::ERROR_QTY); + $this->_removeErrorsFromQuoteAndItem($quoteItem, Data::ERROR_QTY); } } } diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php index c11db1341a7..38abeec1697 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php @@ -6,6 +6,25 @@ namespace Magento\CatalogInventory\Test\Unit\Model\Quote\Item\QuantityValidator\Initializer; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\CatalogInventory\Model\StockRegistry; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem; +use Magento\CatalogInventory\Model\StockState; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator; +use Magento\Framework\Event\Observer; +use Magento\Quote\Model\Quote; +use Magento\Store\Model\Store; +use Magento\Quote\Model\Quote\Item; +use Magento\Catalog\Model\Product; +use Magento\CatalogInventory\Model\Stock\Item as StockMock; +use Magento\Bundle\Model\Product\Type; +use Magento\Framework\DataObject; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Event; +use Magento\CatalogInventory\Helper\Data; +use Magento\Quote\Model\Quote\Item\Option as OptionItem; + /** * Class QuantityValidatorTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -13,7 +32,7 @@ namespace Magento\CatalogInventory\Test\Unit\Model\Quote\Item\QuantityValidator\ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator */ private $quantityValidator; @@ -82,85 +101,56 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase */ private $resultMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $stockState; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $stockItemInitializer; + + protected function setUp() { - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->stockRegistryMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockRegistry::class) - ->disableOriginalConstructor() - ->setMethods(['getStockItem']) - ->getMock(); - $this->optionInitializer = $this->getMockBuilder( - \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class - ) - ->disableOriginalConstructor() - ->getMock(); - $this->stockItemInitializer = $this->getMockBuilder( - \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem::class - ) - ->disableOriginalConstructor() - ->getMock(); - $this->stockState = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockState::class) - ->disableOriginalConstructor() - ->setMethods(['checkQtyIncrements', 'getHasError', 'getQuoteMessageIndex', 'getQuoteMessage']) - ->getMock(); - $this->quantityValidator = $objectManagerHelper->getObject( - \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::class, + $objectManagerHelper = new ObjectManager($this); + $this->stockRegistryMock = $this->getMock(StockRegistry::class, ['getStockItem'], [], '', false); + $this->optionInitializer = $this->getMock(Option::class, [], [], '', false); + $this->stockItemInitializer = $this->getMock(StockItem::class, [], [], '', false); + $this->stockState = $this->getMock(StockState::class, [], [], '', false); + $this->quantityValidator = $objectManagerHelper->getObject(QuantityValidator::class, [ 'optionInitializer' => $this->optionInitializer, 'stockItemInitializer' => $this->stockItemInitializer, 'stockRegistry' => $this->stockRegistryMock, 'stockState' => $this->stockState - ], - '', - false + ] + ); + $this->observerMock = $this->getMock(Observer::class, [], [], '', false); + $this->eventMock = $this->getMock(Event::class, ['getItem'], [], '', false); + $this->quoteMock = $this->getMock(Quote::class, [], [], '', false); + $this->storeMock = $this->getMock(Store::class, [], [], '', false); + $this->quoteItemMock = $this->getMock( + Item::class, + ['getProductId', 'getQuote', 'getQty', 'getProduct', 'getParentItem', + 'addErrorInfo', 'setData', 'getQtyOptions'], + [], '', false + ); + $this->parentItemMock = $this->getMock( + Item::class, + ['getProduct', 'getId', 'getStore'], + [], '', false + ); + $this->productMock = $this->getMock(Product::class, [], [], '', false); + $this->stockItemMock = $this->getMock(StockMock::class, [], [], '', false); + $this->parentStockItemMock = $this->getMock(StockMock::class, [], [], '', false); + $this->typeInstanceMock = $this->getMock(Type::class, [], [], '', false); + $this->resultMock = $this->getMock( + DataObject::class, + ['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError'], + [], '', false ); - $this->observerMock = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) - ->disableOriginalConstructor() - ->setMethods(['getEvent']) - ->getMock(); - $this->eventMock = $this->getMockBuilder(\Magento\Framework\Event::class) - ->disableOriginalConstructor() - ->setMethods(['getItem']) - ->getMock(); - $this->quoteMock = $this->getMockBuilder(\Magento\Quote\Model\Quote::class) - ->disableOriginalConstructor() - ->setMethods(['getIsSuperMode', 'addErrorInfo', 'getQuote', 'getItemsCollection']) - ->getMock(); - $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->setMethods(['getWebsiteId']) - ->getMock(); - $this->quoteItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) - ->disableOriginalConstructor() - ->setMethods( - ['getProductId', 'getQuote', 'getQty', 'getProduct', 'getParentItem', - 'addErrorInfo', 'setData', 'getQtyOptions'] - ) - ->getMock(); - $this->parentItemMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class) - ->disableOriginalConstructor() - ->setMethods(['getProduct', 'getId', 'getStore']) - ->getMock(); - $this->productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) - ->disableOriginalConstructor() - ->setMethods(['getId', 'getStore', 'getTypeInstance']) - ->getMock(); - $this->stockItemMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\Stock\Item::class) - ->disableOriginalConstructor() - ->setMethods(['getIsInStock']) - ->getMock(); - $this->parentStockItemMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\Stock\Item::class) - ->disableOriginalConstructor() - ->setMethods(['getIsInStock']) - ->getMock(); - $this->typeInstanceMock = $this->getMockBuilder(\Magento\CatalogInventory\Model\Stock\Item::class) - ->disableOriginalConstructor() - ->setMethods(['prepareQuoteItemQty']) - ->getMock(); - $this->resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->setMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) - ->getMock(); } /** @@ -181,7 +171,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->method('addErrorInfo') ->with( 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, __('This product is out of stock.') ); $this->quoteMock->expects($this->once()) @@ -189,7 +179,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->with( 'stock', 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, __('Some of the products are out of stock.') ); $this->quantityValidator->validate($this->observerMock); @@ -225,7 +215,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->method('addErrorInfo') ->with( 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, __('This product is out of stock.') ); $this->quoteMock->expects($this->once()) @@ -233,7 +223,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->with( 'stock', 'cataloginventory', - \Magento\CatalogInventory\Helper\Data::ERROR_QTY, + Data::ERROR_QTY, __('Some of the products are out of stock.') ); $this->quantityValidator->validate($this->observerMock); @@ -246,7 +236,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase */ public function testValidateWithOptions() { - $optionMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item\Option::class) + $optionMock = $this->getMockBuilder(OptionItem::class) ->disableOriginalConstructor() ->setMethods(['setHasError']) ->getMock(); @@ -279,8 +269,9 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase * * @return void */ - public function testValidateWithOptionsAndError(){ - $optionMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item\Option::class) + public function testValidateWithOptionsAndError() + { + $optionMock = $this->getMockBuilder(OptionItem::class) ->disableOriginalConstructor() ->setMethods(['setHasError']) ->getMock(); @@ -348,7 +339,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->stockRegistryMock->expects($this->at(0)) ->method('getStockItem') ->willReturn(null); - $this->setExpectedException(\Magento\Framework\Exception\LocalizedException::class); + $this->setExpectedException(LocalizedException::class); $this->quantityValidator->validate($this->observerMock); } @@ -439,7 +430,8 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->willReturn($this->resultMock); } - private function setUpStubForRemoveError(){ + private function setUpStubForRemoveError() + { $quoteItems = [$this->quoteItemMock]; $this->quoteItemMock->expects($this->any()) ->method('getHasError') diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php similarity index 69% rename from dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php rename to dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php index b2716333dd6..50646137505 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Quote/Item/QuantityValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php @@ -4,7 +4,17 @@ * See COPYING.txt for license details. */ namespace Magento\CatalogInventory\Model\Quote\Item; + use Magento\TestFramework\Helper\Bootstrap; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option; +use Magento\Framework\Event\Observer; +use Magento\CatalogInventory\Model\StockState; +use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator; +use Magento\CatalogInventory\Observer\QuantityValidatorObserver; +use Magento\Framework\Event; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\DataObject; +use Magento\Checkout\Model\Session; class QuantityValidatorTest extends \PHPUnit_Framework_TestCase { @@ -47,36 +57,21 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase { /** @var \Magento\Framework\ObjectManagerInterface objectManager */ $this->objectManager = Bootstrap::getObjectManager(); - $this->observerMock = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) - ->disableOriginalConstructor() - ->setMethods(['getEvent']) - ->getMock(); - $this->optionInitializer = $this->getMockBuilder( - \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option::class - ) - ->disableOriginalConstructor() - ->getMock(); - $this->stockState = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockState::class) - ->disableOriginalConstructor() - ->setMethods(['checkQtyIncrements', 'getHasError', 'getQuoteMessageIndex', 'getQuoteMessage']) - ->getMock(); - $this->quantityValidator = $this->objectManager->create( - \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::class, + $this->observerMock = $this->getMock(Observer::class, [], [], '', false); + $this->optionInitializer = $this->getMock(Option::class, [], [], '', false); + $this->stockState = $this->getMock(StockState::class, [], [], '', false); + $this->quantityValidator = $this->objectManager->create(QuantityValidator::class, [ 'optionInitializer' => $this->optionInitializer, 'stockState' => $this->stockState ] ); - $this->observer = $this->objectManager->create( - \Magento\CatalogInventory\Observer\QuantityValidatorObserver::class, + $this->observer = $this->objectManager->create(QuantityValidatorObserver::class, [ 'quantityValidator' => $this->quantityValidator ] ); - $this->eventMock = $this->getMockBuilder(\Magento\Framework\Event::class) - ->disableOriginalConstructor() - ->setMethods(['getItem']) - ->getMock(); + $this->eventMock = $this->getMock(Event::class, ['getItem'], [], '', false); } /** @@ -87,16 +82,13 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase public function testQuoteWithOptions() { /** @var $session \Magento\Checkout\Model\Session */ - $session = $this->objectManager->create(\Magento\Checkout\Model\Session::class); + $session = $this->objectManager->create(Session::class); /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); /** @var $product \Magento\Catalog\Model\Product */ $product = $productRepository->get('bundle-product'); - $resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->setMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) - ->getMock(); + $resultMock = $this->getMock(DataObject::class, [], [], '', false); $this->stockState->expects($this->any())->method('checkQtyIncrements')->willReturn($resultMock); /* @var $quoteItem \Magento\Quote\Model\Quote\Item */ $quoteItem = $this->_getQuoteItemIdByProductId($session->getQuote(), $product->getId()); @@ -115,17 +107,18 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase public function testQuoteWithOptionsWithErrors() { /** @var $session \Magento\Checkout\Model\Session */ - $session = $this->objectManager->create(\Magento\Checkout\Model\Session::class); + $session = $this->objectManager->create(Session::class); /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); /** @var $product \Magento\Catalog\Model\Product */ $product = $productRepository->get('bundle-product'); /* @var $quoteItem \Magento\Quote\Model\Quote\Item */ $quoteItem = $this->_getQuoteItemIdByProductId($session->getQuote(), $product->getId()); - $resultMock = $this->getMockBuilder(\Magento\Framework\DataObject::class) - ->disableOriginalConstructor() - ->setMethods(['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError']) - ->getMock(); + $resultMock = $this->getMock( + DataObject::class, + ['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError'], + [], '', false + ); $this->observerMock->expects($this->once())->method('getEvent')->willReturn($this->eventMock); $this->eventMock->expects($this->once())->method('getItem')->willReturn($quoteItem); $this->stockState->expects($this->any())->method('checkQtyIncrements')->willReturn($resultMock); @@ -153,4 +146,4 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase } $this->fail('Test failed since no quoteItem found by productId '.$productId); } -} \ No newline at end of file +} -- GitLab From c2b8fcc2cd118b7ae1c838eab5e2aea63277c7ff Mon Sep 17 00:00:00 2001 From: Arpita Barua <abarua@magento.com> Date: Thu, 8 Sep 2016 11:16:48 -0500 Subject: [PATCH 834/838] MAGETWO-55287: Missing product name in bundle product error message - Cleaning up Acceptance Tests --- .../Model/Quote/Item/QuantityValidator.php | 1 + .../Initializer/QuantityValidatorTest.php | 24 ++++++++++++------- .../Quote/Item/QuantityValidatorTest.php | 10 +++++--- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php index ca18b7ec904..5921a24122b 100644 --- a/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php +++ b/app/code/Magento/CatalogInventory/Model/Quote/Item/QuantityValidator.php @@ -15,6 +15,7 @@ use Magento\CatalogInventory\Helper\Data; use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\Option; use Magento\CatalogInventory\Model\Quote\Item\QuantityValidator\Initializer\StockItem; use Magento\Framework\Event\Observer; + /** * Class QuantityValidator */ diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php index 38abeec1697..1dedbbe6967 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php @@ -111,7 +111,6 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase */ private $stockItemInitializer; - protected function setUp() { $objectManagerHelper = new ObjectManager($this); @@ -119,7 +118,8 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->optionInitializer = $this->getMock(Option::class, [], [], '', false); $this->stockItemInitializer = $this->getMock(StockItem::class, [], [], '', false); $this->stockState = $this->getMock(StockState::class, [], [], '', false); - $this->quantityValidator = $objectManagerHelper->getObject(QuantityValidator::class, + $this->quantityValidator = $objectManagerHelper->getObject( + QuantityValidator::class, [ 'optionInitializer' => $this->optionInitializer, 'stockItemInitializer' => $this->stockItemInitializer, @@ -135,12 +135,16 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase Item::class, ['getProductId', 'getQuote', 'getQty', 'getProduct', 'getParentItem', 'addErrorInfo', 'setData', 'getQtyOptions'], - [], '', false + [], + '', + false ); $this->parentItemMock = $this->getMock( Item::class, ['getProduct', 'getId', 'getStore'], - [], '', false + [], + '', + false ); $this->productMock = $this->getMock(Product::class, [], [], '', false); $this->stockItemMock = $this->getMock(StockMock::class, [], [], '', false); @@ -149,7 +153,9 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->resultMock = $this->getMock( DataObject::class, ['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError'], - [], '', false + [], + '', + false ); } @@ -171,7 +177,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->method('addErrorInfo') ->with( 'cataloginventory', - Data::ERROR_QTY, + Data::ERROR_QTY, __('This product is out of stock.') ); $this->quoteMock->expects($this->once()) @@ -179,7 +185,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->with( 'stock', 'cataloginventory', - Data::ERROR_QTY, + Data::ERROR_QTY, __('Some of the products are out of stock.') ); $this->quantityValidator->validate($this->observerMock); @@ -215,7 +221,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->method('addErrorInfo') ->with( 'cataloginventory', - Data::ERROR_QTY, + Data::ERROR_QTY, __('This product is out of stock.') ); $this->quoteMock->expects($this->once()) @@ -223,7 +229,7 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase ->with( 'stock', 'cataloginventory', - Data::ERROR_QTY, + Data::ERROR_QTY, __('Some of the products are out of stock.') ); $this->quantityValidator->validate($this->observerMock); diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php index 50646137505..12f6391d303 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php @@ -60,13 +60,15 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $this->observerMock = $this->getMock(Observer::class, [], [], '', false); $this->optionInitializer = $this->getMock(Option::class, [], [], '', false); $this->stockState = $this->getMock(StockState::class, [], [], '', false); - $this->quantityValidator = $this->objectManager->create(QuantityValidator::class, + $this->quantityValidator = $this->objectManager->create( + QuantityValidator::class, [ 'optionInitializer' => $this->optionInitializer, 'stockState' => $this->stockState ] ); - $this->observer = $this->objectManager->create(QuantityValidatorObserver::class, + $this->observer = $this->objectManager->create( + QuantityValidatorObserver::class, [ 'quantityValidator' => $this->quantityValidator ] @@ -117,7 +119,9 @@ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase $resultMock = $this->getMock( DataObject::class, ['checkQtyIncrements', 'getMessage', 'getQuoteMessage', 'getHasError'], - [], '', false + [], + '', + false ); $this->observerMock->expects($this->once())->method('getEvent')->willReturn($this->eventMock); $this->eventMock->expects($this->once())->method('getItem')->willReturn($quoteItem); -- GitLab From cb6587c3d70d19c5377ae920a7500e9abcf78687 Mon Sep 17 00:00:00 2001 From: Arpita Barua <abarua@magento.com> Date: Thu, 8 Sep 2016 12:11:59 -0500 Subject: [PATCH 835/838] MAGETWO-55287: Missing product name in bundle product error message - Cleaning up Acceptance Tests --- .../Initializer/QuantityValidatorTest.php | 1 + .../Model/Quote/Item/QuantityValidatorTest.php | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php index 1dedbbe6967..7fd886f3815 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Quote/Item/QuantityValidator/Initializer/QuantityValidatorTest.php @@ -28,6 +28,7 @@ use Magento\Quote\Model\Quote\Item\Option as OptionItem; /** * Class QuantityValidatorTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php index 12f6391d303..4da19b6c103 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php @@ -16,10 +16,16 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\DataObject; use Magento\Checkout\Model\Session; + +/** + * Class QuantityValidatorTest + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class QuantityValidatorTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\CatalogInventory\Model\Quote\Item\QuantityValidator + * @var QuantityValidator */ private $quantityValidator; -- GitLab From b88c323f39f66209c300d9f987d671254fa364a7 Mon Sep 17 00:00:00 2001 From: Arpita Barua <abarua@magento.com> Date: Thu, 8 Sep 2016 12:19:40 -0500 Subject: [PATCH 836/838] MAGETWO-55287: Missing product name in bundle product error message - Cleaning up Acceptance Tests --- .../CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php index 4da19b6c103..12cbbb36e3d 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php @@ -16,7 +16,6 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\DataObject; use Magento\Checkout\Model\Session; - /** * Class QuantityValidatorTest * -- GitLab From c3ed73da517929ce2e5f0eac76269ba31a9ea849 Mon Sep 17 00:00:00 2001 From: aakimov <aakimov@magento.com> Date: Wed, 7 Sep 2016 17:08:38 +0300 Subject: [PATCH 837/838] MAGETWO-58067: [GitHub] Data Loss for Country Multiselect in Backend on Website Level --- .../system/shipping/applicable_country.phtml | 7 +++-- .../Form/Field/Select/Allowspecific.php | 30 ++++++++++++++++--- .../Form/Field/Select/AllowspecificTest.php | 6 ++-- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml b/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml index 6d003c6cb68..7729b96f5ac 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml @@ -61,11 +61,14 @@ CountryModel.prototype = { if (applyCountryElement && applyCountryElement.id) { var specifCountryElement = $(applyCountryElement.id.replace(/sallowspecific/, 'specificcountry')); var showMethodElement = $(applyCountryElement.id.replace(/sallowspecific/, 'showmethod')); + // 'Use Default' checkbox of the related county list UI element + var useDefaultElement = document.getElementById(specifCountryElement.id + '_inherit'); + //var specifErrMsgElement = $(applyCountryElement.id.replace(/sallowspecific/, 'specificerrmsg')); if (specifCountryElement) { if (applyCountryElement.value == 1) { - //if specific country element selected - specifCountryElement.enable(); + // enable related country select only if its 'Use Default' checkbox is absent or is unchecked + specifCountryElement.disabled = (useDefaultElement) ? useDefaultElement.checked : false; if (showMethodElement) { this.showElement(showMethodElement.up(1)); } diff --git a/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php b/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php index 6eb813e8396..9dd8d78ac17 100644 --- a/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php +++ b/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php @@ -22,10 +22,32 @@ class Allowspecific extends \Magento\Framework\Data\Form\Element\Select */ public function getAfterElementHtml() { - $javaScript = "\n <script type=\"text/javascript\">require(['prototype'], function(){\n Event.observe('{$this->getHtmlId()}', 'change', function(){\n specific=\$('{$this - ->getHtmlId()}').value;\n \$('{$this - ->_getSpecificCountryElementId()}').disabled = (!specific || specific!=1);\n });\n });</script>"; - return $javaScript . parent::getAfterElementHtml(); + $elementId = $this->getHtmlId(); + $countryListId = $this->_getSpecificCountryElementId(); + $useDefaultElementId = $countryListId . '_inherit'; + + $elementJavaScript = <<<HTML +<script type="text/javascript"> +//<![CDATA[ +document.getElementById('{$elementId}').addEventListener('change', function(event) { + var isCountrySpecific = event.target.value == 1, + specificCountriesElement = document.getElementById('{$countryListId}'), + // 'Use Default' checkbox of the related county list UI element + useDefaultElement = document.getElementById('{$useDefaultElementId}'); + + if (isCountrySpecific) { + // enable related country select only if its 'Use Default' checkbox is absent or is unchecked + specificCountriesElement.disabled = (useDefaultElement) ? useDefaultElement.checked : false; + } else { + // disable related country select if all countries are used + specificCountriesElement.disabled = true; + } +}); +//]]> +</script> +HTML; + + return $elementJavaScript . parent::getAfterElementHtml(); } /** diff --git a/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Field/Select/AllowspecificTest.php b/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Field/Select/AllowspecificTest.php index 295da579693..3a0f751c8b2 100644 --- a/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Field/Select/AllowspecificTest.php +++ b/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Field/Select/AllowspecificTest.php @@ -37,14 +37,14 @@ class AllowspecificTest extends \PHPUnit_Framework_TestCase public function testGetAfterElementHtml() { $this->_formMock->expects( - $this->exactly(2) + $this->once() )->method( 'getHtmlIdPrefix' )->will( $this->returnValue('test_prefix_') ); $this->_formMock->expects( - $this->exactly(2) + $this->once() )->method( 'getHtmlIdSuffix' )->will( @@ -57,7 +57,7 @@ class AllowspecificTest extends \PHPUnit_Framework_TestCase $actual = $this->_object->getAfterElementHtml(); - $this->assertStringEndsWith($afterHtmlCode, $actual); + $this->assertStringEndsWith('</script>' . $afterHtmlCode, $actual); $this->assertStringStartsWith('<script type="text/javascript">', trim($actual)); $this->assertContains('test_prefix_spec_element_test_suffix', $actual); } -- GitLab From 0bb7c3fa466b067eb5fa747b95da4a24b830bd89 Mon Sep 17 00:00:00 2001 From: aakimov <aakimov@magento.com> Date: Fri, 9 Sep 2016 11:03:03 +0300 Subject: [PATCH 838/838] MAGETWO-58067: [GitHub] Data Loss for Country Multiselect in Backend on Website Level --- .../templates/system/shipping/applicable_country.phtml | 2 +- .../Block/System/Config/Form/Field/Select/Allowspecific.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml b/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml index 7729b96f5ac..0a526f63ebd 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/system/shipping/applicable_country.phtml @@ -68,7 +68,7 @@ CountryModel.prototype = { if (specifCountryElement) { if (applyCountryElement.value == 1) { // enable related country select only if its 'Use Default' checkbox is absent or is unchecked - specifCountryElement.disabled = (useDefaultElement) ? useDefaultElement.checked : false; + specifCountryElement.disabled = useDefaultElement ? useDefaultElement.checked : false; if (showMethodElement) { this.showElement(showMethodElement.up(1)); } diff --git a/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php b/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php index 9dd8d78ac17..8b7a2ac7dd2 100644 --- a/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php +++ b/app/code/Magento/Config/Block/System/Config/Form/Field/Select/Allowspecific.php @@ -37,7 +37,7 @@ document.getElementById('{$elementId}').addEventListener('change', function(even if (isCountrySpecific) { // enable related country select only if its 'Use Default' checkbox is absent or is unchecked - specificCountriesElement.disabled = (useDefaultElement) ? useDefaultElement.checked : false; + specificCountriesElement.disabled = useDefaultElement ? useDefaultElement.checked : false; } else { // disable related country select if all countries are used specificCountriesElement.disabled = true; -- GitLab